package com.example.newdemo.view.image.svg;

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Path.FillType;
import android.graphics.PathEffect;
import android.graphics.PathMeasure;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.Typeface;
import android.os.Build.VERSION;
import android.util.Base64;
import android.util.Log;

import com.example.newdemo.view.image.svg.CSSParser.Rule;
import com.example.newdemo.view.image.svg.PreserveAspectRatio.Scale;
import com.example.newdemo.view.image.svg.SVG.Box;
import com.example.newdemo.view.image.svg.SVG.Circle;
import com.example.newdemo.view.image.svg.SVG.ClipPath;
import com.example.newdemo.view.image.svg.SVG.Colour;
import com.example.newdemo.view.image.svg.SVG.CurrentColor;
import com.example.newdemo.view.image.svg.SVG.Ellipse;
import com.example.newdemo.view.image.svg.SVG.GradientElement;
import com.example.newdemo.view.image.svg.SVG.GradientSpread;
import com.example.newdemo.view.image.svg.SVG.GraphicsElement;
import com.example.newdemo.view.image.svg.SVG.Group;
import com.example.newdemo.view.image.svg.SVG.Image;
import com.example.newdemo.view.image.svg.SVG.Length;
import com.example.newdemo.view.image.svg.SVG.Line;
import com.example.newdemo.view.image.svg.SVG.Marker;
import com.example.newdemo.view.image.svg.SVG.Mask;
import com.example.newdemo.view.image.svg.SVG.PaintReference;
import com.example.newdemo.view.image.svg.SVG.Path;
import com.example.newdemo.view.image.svg.SVG.PathDefinition;
import com.example.newdemo.view.image.svg.SVG.PathInterface;
import com.example.newdemo.view.image.svg.SVG.Pattern;
import com.example.newdemo.view.image.svg.SVG.PolyLine;
import com.example.newdemo.view.image.svg.SVG.Polygon;
import com.example.newdemo.view.image.svg.SVG.Rect;
import com.example.newdemo.view.image.svg.SVG.SolidColor;
import com.example.newdemo.view.image.svg.SVG.Stop;
import com.example.newdemo.view.image.svg.SVG.Style;
import com.example.newdemo.view.image.svg.SVG.Style.FontStyle;
import com.example.newdemo.view.image.svg.SVG.Style.TextAnchor;
import com.example.newdemo.view.image.svg.SVG.Style.TextDecoration;
import com.example.newdemo.view.image.svg.SVG.Style.TextDirection;
import com.example.newdemo.view.image.svg.SVG.Style.VectorEffect;
import com.example.newdemo.view.image.svg.SVG.Svg;
import com.example.newdemo.view.image.svg.SVG.SvgConditional;
import com.example.newdemo.view.image.svg.SVG.SvgContainer;
import com.example.newdemo.view.image.svg.SVG.SvgElement;
import com.example.newdemo.view.image.svg.SVG.SvgElementBase;
import com.example.newdemo.view.image.svg.SVG.SvgLinearGradient;
import com.example.newdemo.view.image.svg.SVG.SvgObject;
import com.example.newdemo.view.image.svg.SVG.SvgPaint;
import com.example.newdemo.view.image.svg.SVG.SvgRadialGradient;
import com.example.newdemo.view.image.svg.SVG.Switch;
import com.example.newdemo.view.image.svg.SVG.Symbol;
import com.example.newdemo.view.image.svg.SVG.TRef;
import com.example.newdemo.view.image.svg.SVG.TSpan;
import com.example.newdemo.view.image.svg.SVG.Text;
import com.example.newdemo.view.image.svg.SVG.TextContainer;
import com.example.newdemo.view.image.svg.SVG.TextPath;
import com.example.newdemo.view.image.svg.SVG.TextSequence;
import com.example.newdemo.view.image.svg.SVG.Unit;
import com.example.newdemo.view.image.svg.SVG.Use;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.Stack;


public class SVGAndroidRenderer {
    private static final String TAG = "SVGAndroidRenderer";
    private Canvas canvas;
    private SVG.Box canvasViewPort;
    private float dpi;
    private boolean directRenderingMode;
    private SVG document;
    private SVGAndroidRenderer.RendererState state;
    private Stack<SVGAndroidRenderer.RendererState> stateStack;
    private Stack<SvgContainer> parentStack;
    private Stack<Matrix> matrixStack;
    private Stack<Canvas> canvasStack;
    private Stack<Bitmap> bitmapStack;
    private static final float BEZIER_ARC_FACTOR = 0.5522848F;
    private static final int LUMINANCE_FACTOR_SHIFT = 15;
    private static final int LUMINANCE_TO_ALPHA_RED = 6963;
    private static final int LUMINANCE_TO_ALPHA_GREEN = 23442;
    private static final int LUMINANCE_TO_ALPHA_BLUE = 2362;
    private static final String DEFAULT_FONT_FAMILY = "sans-serif";

    private void resetState() {
        this.state = new SVGAndroidRenderer.RendererState();
        this.stateStack = new Stack();
        this.updateStyle(this.state, Style.getDefaultStyle());
        this.state.viewPort = this.canvasViewPort;
        this.state.spacePreserve = false;
        this.state.directRendering = this.directRenderingMode;
        this.stateStack.push((SVGAndroidRenderer.RendererState)this.state.clone());
        this.canvasStack = new Stack();
        this.bitmapStack = new Stack();
        this.matrixStack = new Stack();
        this.parentStack = new Stack();
    }

    protected SVGAndroidRenderer(Canvas canvas, Box viewPort, float defaultDPI) {
        this.canvas = canvas;
        this.dpi = defaultDPI;
        this.canvasViewPort = viewPort;
    }

    protected float getDPI() {
        return this.dpi;
    }

    protected float getCurrentFontSize() {
        return this.state.fillPaint.getTextSize();
    }

    protected float getCurrentFontXHeight() {
        return this.state.fillPaint.getTextSize() / 2.0F;
    }

    protected SVG.Box getCurrentViewPortInUserUnits() {
        return this.state.viewBox != null ? this.state.viewBox : this.state.viewPort;
    }

    protected void renderDocument(SVG document, Box viewBox, PreserveAspectRatio positioning, boolean directRenderingMode) {
        this.document = document;
        this.directRenderingMode = directRenderingMode;
        SVG.Svg rootObj = document.getRootElement();
        if (rootObj == null) {
            warn("Nothing to render. Document is empty.");
        } else {
            this.resetState();
            this.checkXMLSpaceAttribute(rootObj);
            this.render(rootObj, rootObj.width, rootObj.height, viewBox != null ? viewBox : rootObj.viewBox, positioning != null ? positioning : rootObj.preserveAspectRatio);
        }
    }

    private void render(SvgObject obj) {
        if (!(obj instanceof SVG.NotDirectlyRendered)) {
            this.statePush();
            this.checkXMLSpaceAttribute(obj);
            if (obj instanceof Svg) {
                this.render((Svg)obj);
            } else if (obj instanceof Use) {
                this.render((Use)obj);
            } else if (obj instanceof Switch) {
                this.render((Switch)obj);
            } else if (obj instanceof Group) {
                this.render((Group)obj);
            } else if (obj instanceof Image) {
                this.render((Image)obj);
            } else if (obj instanceof Path) {
                this.render((Path)obj);
            } else if (obj instanceof Rect) {
                this.render((Rect)obj);
            } else if (obj instanceof Circle) {
                this.render((Circle)obj);
            } else if (obj instanceof Ellipse) {
                this.render((Ellipse)obj);
            } else if (obj instanceof Line) {
                this.render((Line)obj);
            } else if (obj instanceof Polygon) {
                this.render((Polygon)obj);
            } else if (obj instanceof PolyLine) {
                this.render((PolyLine)obj);
            } else if (obj instanceof Text) {
                this.render((Text)obj);
            }

            this.statePop();
        }
    }

    private void renderChildren(SvgContainer obj, boolean isContainer) {
        if (isContainer) {
            this.parentPush(obj);
        }

        Iterator var4 = obj.getChildren().iterator();

        while(var4.hasNext()) {
            SvgObject child = (SvgObject)var4.next();
            this.render(child);
        }

        if (isContainer) {
            this.parentPop();
        }

    }

    private void statePush() {
        this.canvas.save();
        this.stateStack.push(this.state);
        this.state = (SVGAndroidRenderer.RendererState)this.state.clone();
    }

    private void statePop() {
        this.canvas.restore();
        this.state = (SVGAndroidRenderer.RendererState)this.stateStack.pop();
    }

    private void parentPush(SvgContainer obj) {
        this.parentStack.push(obj);
        this.matrixStack.push(this.canvas.getMatrix());
    }

    private void parentPop() {
        this.parentStack.pop();
        this.matrixStack.pop();
    }

    private void updateStyleForElement(SVGAndroidRenderer.RendererState state, SvgElementBase obj) {
        boolean isRootSVG = obj.parent == null;
        state.style.resetNonInheritingProperties(isRootSVG);
        if (obj.baseStyle != null) {
            this.updateStyle(state, obj.baseStyle);
        }

        if (this.document.hasCSSRules()) {
            Iterator var5 = this.document.getCSSRules().iterator();

            while(var5.hasNext()) {
                Rule rule = (Rule)var5.next();
                if (CSSParser.ruleMatch(rule.selector, obj)) {
                    this.updateStyle(state, rule.style);
                }
            }
        }

        if (obj.style != null) {
            this.updateStyle(state, obj.style);
        }

    }

    private void checkXMLSpaceAttribute(SvgObject obj) {
        if (obj instanceof SvgElementBase) {
            SvgElementBase bobj = (SvgElementBase)obj;
            if (bobj.spacePreserve != null) {
                this.state.spacePreserve = bobj.spacePreserve;
            }

        }
    }

    private void doFilledPath(SvgElement obj, android.graphics.Path path) {
        if (this.state.style.fill instanceof PaintReference) {
            SvgObject ref = this.document.resolveIRI(((PaintReference)this.state.style.fill).href);
            if (ref instanceof Pattern) {
                Pattern pattern = (Pattern)ref;
                this.fillWithPattern(obj, path, pattern);
                return;
            }
        }

        this.canvas.drawPath(path, this.state.fillPaint);
    }

    private void doStroke(android.graphics.Path path) {
        if (this.state.style.vectorEffect == VectorEffect.NonScalingStroke) {
            Matrix currentMatrix = this.canvas.getMatrix();
            android.graphics.Path transformedPath = new android.graphics.Path();
            path.transform(currentMatrix, transformedPath);
            this.canvas.setMatrix(new Matrix());
            Shader shader = this.state.strokePaint.getShader();
            Matrix currentShaderMatrix = new Matrix();
            if (shader != null) {
                shader.getLocalMatrix(currentShaderMatrix);
                Matrix newShaderMatrix = new Matrix(currentShaderMatrix);
                newShaderMatrix.postConcat(currentMatrix);
                shader.setLocalMatrix(newShaderMatrix);
            }

            this.canvas.drawPath(transformedPath, this.state.strokePaint);
            this.canvas.setMatrix(currentMatrix);
            if (shader != null) {
                shader.setLocalMatrix(currentShaderMatrix);
            }
        } else {
            this.canvas.drawPath(path, this.state.strokePaint);
        }

    }

    private static void warn(String format, Object... args) {
        Log.w("SVGAndroidRenderer", String.format(format, args));
    }

    private static void error(String format, Object... args) {
        Log.e("SVGAndroidRenderer", String.format(format, args));
    }

    private static void debug(String format, Object... args) {
    }

    private static void info(String format, Object... args) {
        Log.i("SVGAndroidRenderer", String.format(format, args));
    }

    private void render(Svg obj) {
        this.render(obj, obj.width, obj.height);
    }

    private void render(Svg obj, Length width, Length height) {
        this.render(obj, width, height, obj.viewBox, obj.preserveAspectRatio);
    }

    private void render(Svg obj, Length width, Length height, Box viewBox, PreserveAspectRatio positioning) {
        debug("Svg render");
        if ((width == null || !width.isZero()) && (height == null || !height.isZero())) {
            if (positioning == null) {
                positioning = obj.preserveAspectRatio != null ? obj.preserveAspectRatio : PreserveAspectRatio.LETTERBOX;
            }

            this.updateStyleForElement(this.state, obj);
            if (this.display()) {
                float _x = 0.0F;
                float _y = 0.0F;
                if (obj.parent != null) {
                    _x = obj.x != null ? obj.x.floatValueX(this) : 0.0F;
                    _y = obj.y != null ? obj.y.floatValueY(this) : 0.0F;
                }

                Box viewPortUser = this.getCurrentViewPortInUserUnits();
                float _w = width != null ? width.floatValueX(this) : viewPortUser.width;
                float _h = height != null ? height.floatValueY(this) : viewPortUser.height;
                this.state.viewPort = new Box(_x, _y, _w, _h);
                if (!this.state.style.overflow) {
                    this.setClipRect(this.state.viewPort.minX, this.state.viewPort.minY, this.state.viewPort.width, this.state.viewPort.height);
                }

                this.checkForClipPath(obj, this.state.viewPort);
                if (viewBox != null) {
                    this.canvas.concat(this.calculateViewBoxTransform(this.state.viewPort, viewBox, positioning));
                    this.state.viewBox = obj.viewBox;
                } else {
                    this.canvas.translate(_x, _y);
                }

                boolean compositing = this.pushLayer();
                this.viewportFill();
                this.renderChildren(obj, true);
                if (compositing) {
                    this.popLayer(obj);
                }

                this.updateParentBoundingBox(obj);
            }
        }
    }

    private void render(Group obj) {
        debug("Group render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (obj.transform != null) {
                this.canvas.concat(obj.transform);
            }

            this.checkForClipPath(obj);
            boolean compositing = this.pushLayer();
            this.renderChildren(obj, true);
            if (compositing) {
                this.popLayer(obj);
            }

            this.updateParentBoundingBox(obj);
        }
    }

    private void updateParentBoundingBox(SvgElement obj) {
        if (obj.parent != null) {
            if (obj.boundingBox != null) {
                Matrix m = new Matrix();
                if (((Matrix)this.matrixStack.peek()).invert(m)) {
                    float[] pts = new float[]{obj.boundingBox.minX,
                            obj.boundingBox.minY,
                            obj.boundingBox.maxX(),
                            obj.boundingBox.minY,
                            obj.boundingBox.maxX(),
                            obj.boundingBox.maxY(),
                            obj.boundingBox.minX,
                            obj.boundingBox.maxY()};

                    m.preConcat(this.canvas.getMatrix());
                    m.mapPoints(pts);
                    RectF rect = new RectF(pts[0], pts[1], pts[0], pts[1]);

                    for(int i = 2; i <= 6; i += 2) {
                        if (pts[i] < rect.left) {
                            rect.left = pts[i];
                        }

                        if (pts[i] > rect.right) {
                            rect.right = pts[i];
                        }

                        if (pts[i + 1] < rect.top) {
                            rect.top = pts[i + 1];
                        }

                        if (pts[i + 1] > rect.bottom) {
                            rect.bottom = pts[i + 1];
                        }
                    }

                    SvgElement parent = (SvgElement)this.parentStack.peek();
                    if (parent.boundingBox == null) {
                        parent.boundingBox = Box.fromLimits(rect.left, rect.top, rect.right, rect.bottom);
                    } else {
                        parent.boundingBox.union(Box.fromLimits(rect.left, rect.top, rect.right, rect.bottom));
                    }
                }

            }
        }
    }

    @SuppressLint("WrongConstant")
    private boolean pushLayer() {
        if (!this.requiresCompositing()) {
            return false;
        } else {
            this.canvas.saveLayerAlpha((RectF)null, this.clamp255(this.state.style.opacity), 4);
            this.stateStack.push(this.state);
            this.state = (SVGAndroidRenderer.RendererState)this.state.clone();
            if (this.state.style.mask != null && this.state.directRendering) {
                SvgObject ref = this.document.resolveIRI(this.state.style.mask);
                if (ref == null || !(ref instanceof Mask)) {
                    error("Mask reference '%s' not found", this.state.style.mask);
                    this.state.style.mask = null;
                    return true;
                }

                this.canvasStack.push(this.canvas);
                this.duplicateCanvas();
            }

            return true;
        }
    }

    private void popLayer(SvgElement obj) {
        if (this.state.style.mask != null && this.state.directRendering) {
            SvgObject ref = this.document.resolveIRI(this.state.style.mask);
            this.duplicateCanvas();
            this.renderMask((Mask)ref, obj);
            Bitmap maskedContent = this.processMaskBitmaps();
            this.canvas = (Canvas)this.canvasStack.pop();
            this.canvas.save();
            this.canvas.setMatrix(new Matrix());
            this.canvas.drawBitmap(maskedContent, 0.0F, 0.0F, this.state.fillPaint);
            maskedContent.recycle();
            this.canvas.restore();
        }

        this.statePop();
    }

    private boolean requiresCompositing() {
        if (this.state.style.mask != null && !this.state.directRendering) {
            warn("Masks are not supported when using getPicture()");
        }

        return this.state.style.opacity < 1.0F || this.state.style.mask != null && this.state.directRendering;
    }

    private void duplicateCanvas() {
        try {
            Bitmap newBM = Bitmap.createBitmap(this.canvas.getWidth(), this.canvas.getHeight(), Config.ARGB_8888);
            this.bitmapStack.push(newBM);
            Canvas newCanvas = new Canvas(newBM);
            newCanvas.setMatrix(this.canvas.getMatrix());
            this.canvas = newCanvas;
        } catch (OutOfMemoryError var3) {
            error("Not enough memory to create temporary bitmaps for mask processing");
            throw var3;
        }
    }

    private Bitmap processMaskBitmaps() {
        Bitmap mask = (Bitmap)this.bitmapStack.pop();
        Bitmap maskedContent = (Bitmap)this.bitmapStack.pop();
        int w = mask.getWidth();
        int h = mask.getHeight();
        int[] maskBuf = new int[w];
        int[] maskedContentBuf = new int[w];

        for(int y = 0; y < h; ++y) {
            mask.getPixels(maskBuf, 0, w, 0, y, w, 1);
            maskedContent.getPixels(maskedContentBuf, 0, w, 0, y, w, 1);

            for(int x = 0; x < w; ++x) {
                int px = maskBuf[x];
                int b = px & 255;
                int g = px >> 8 & 255;
                int r = px >> 16 & 255;
                int a = px >> 24 & 255;
                if (a == 0) {
                    maskedContentBuf[x] = 0;
                } else {
                    int maskAlpha = (r * 6963 + g * 23442 + b * 2362) * a / 8355840;
                    int content = maskedContentBuf[x];
                    int contentAlpha = content >> 24 & 255;
                    contentAlpha = contentAlpha * maskAlpha / 255;
                    maskedContentBuf[x] = content & 16777215 | contentAlpha << 24;
                }
            }

            maskedContent.setPixels(maskedContentBuf, 0, w, 0, y, w, 1);
        }

        mask.recycle();
        return maskedContent;
    }

    private void render(Switch obj) {
        debug("Switch render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (obj.transform != null) {
                this.canvas.concat(obj.transform);
            }

            this.checkForClipPath(obj);
            boolean compositing = this.pushLayer();
            this.renderSwitchChild(obj);
            if (compositing) {
                this.popLayer(obj);
            }

            this.updateParentBoundingBox(obj);
        }
    }

    private void renderSwitchChild(Switch obj) {
        String deviceLanguage = Locale.getDefault().getLanguage();
        SVGExternalFileResolver fileResolver = this.document.getFileResolver();
        Iterator var5 = obj.getChildren().iterator();

        label77:
        while(var5.hasNext()) {
            SvgObject child = (SvgObject)var5.next();
            if (child instanceof SvgConditional) {
                SvgConditional condObj = (SvgConditional)child;
                if (condObj.getRequiredExtensions() == null) {
                    Set<String> syslang = condObj.getSystemLanguage();
                    if (syslang == null || !syslang.isEmpty() && syslang.contains(deviceLanguage)) {
                        Set<String> reqfeat = condObj.getRequiredFeatures();
                        if (reqfeat == null || !reqfeat.isEmpty() && SVGParser.supportedFeatures.containsAll(reqfeat)) {
                            Set<String> reqfmts = condObj.getRequiredFormats();
                            if (reqfmts != null) {
                                if (reqfmts.isEmpty() || fileResolver == null) {
                                    continue;
                                }

                                Iterator var11 = reqfmts.iterator();

                                while(var11.hasNext()) {
                                    String mimeType = (String)var11.next();
                                    if (!fileResolver.isFormatSupported(mimeType)) {
                                        continue label77;
                                    }
                                }
                            }

                            Set<String> reqfonts = condObj.getRequiredFonts();
                            if (reqfonts != null) {
                                if (reqfonts.isEmpty() || fileResolver == null) {
                                    continue;
                                }

                                Iterator var12 = reqfonts.iterator();

                                while(var12.hasNext()) {
                                    String fontName = (String)var12.next();
                                    if (fileResolver.resolveFont(fontName, this.state.style.fontWeight, String.valueOf(this.state.style.fontStyle)) == null) {
                                        continue label77;
                                    }
                                }
                            }

                            this.render(child);
                            break;
                        }
                    }
                }
            }
        }

    }

    private void render(Use obj) {
        debug("Use render");
        if ((obj.width == null || !obj.width.isZero()) && (obj.height == null || !obj.height.isZero())) {
            this.updateStyleForElement(this.state, obj);
            if (this.display()) {
                SvgObject ref = obj.document.resolveIRI(obj.href);
                if (ref == null) {
                    error("Use reference '%s' not found", obj.href);
                } else {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    Matrix m = new Matrix();
                    float _x = obj.x != null ? obj.x.floatValueX(this) : 0.0F;
                    float _y = obj.y != null ? obj.y.floatValueY(this) : 0.0F;
                    m.preTranslate(_x, _y);
                    this.canvas.concat(m);
                    this.checkForClipPath(obj);
                    boolean compositing = this.pushLayer();
                    this.parentPush(obj);
                    Length _h;
                    if (ref instanceof Svg) {
                        this.statePush();
                        Svg svgElem = (Svg)ref;
                        _h = obj.width != null ? obj.width : svgElem.width;
                        _h = obj.height != null ? obj.height : svgElem.height;
                        this.render(svgElem, _h, _h);
                        this.statePop();
                    } else if (ref instanceof Symbol) {
                        Length _w = obj.width != null ? obj.width : new Length(100.0F, Unit.percent);
                        _h = obj.height != null ? obj.height : new Length(100.0F, Unit.percent);
                        this.statePush();
                        this.render((Symbol)ref, _w, _h);
                        this.statePop();
                    } else {
                        this.render(ref);
                    }

                    this.parentPop();
                    if (compositing) {
                        this.popLayer(obj);
                    }

                    this.updateParentBoundingBox(obj);
                }
            }
        }
    }

    private void render(Path obj) {
        debug("Path render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                if (this.state.hasStroke || this.state.hasFill) {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    android.graphics.Path path = (new SVGAndroidRenderer.PathConverter(obj.d)).getPath();
                    if (obj.boundingBox == null) {
                        obj.boundingBox = this.calculatePathBounds(path);
                    }

                    this.updateParentBoundingBox(obj);
                    this.checkForGradiantsAndPatterns(obj);
                    this.checkForClipPath(obj);
                    boolean compositing = this.pushLayer();
                    if (this.state.hasFill) {
                        path.setFillType(this.getFillTypeFromState());
                        this.doFilledPath(obj, path);
                    }

                    if (this.state.hasStroke) {
                        this.doStroke(path);
                    }

                    this.renderMarkers(obj);
                    if (compositing) {
                        this.popLayer(obj);
                    }

                }
            }
        }
    }

    private Box calculatePathBounds(android.graphics.Path path) {
        RectF pathBounds = new RectF();
        path.computeBounds(pathBounds, true);
        return new Box(pathBounds.left, pathBounds.top, pathBounds.width(), pathBounds.height());
    }

    private void render(Rect obj) {
        debug("Rect render");
        if (obj.width != null && obj.height != null && !obj.width.isZero() && !obj.height.isZero()) {
            this.updateStyleForElement(this.state, obj);
            if (this.display()) {
                if (this.visible()) {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    android.graphics.Path path = this.makePathAndBoundingBox(obj);
                    this.updateParentBoundingBox(obj);
                    this.checkForGradiantsAndPatterns(obj);
                    this.checkForClipPath(obj);
                    boolean compositing = this.pushLayer();
                    if (this.state.hasFill) {
                        this.doFilledPath(obj, path);
                    }

                    if (this.state.hasStroke) {
                        this.doStroke(path);
                    }

                    if (compositing) {
                        this.popLayer(obj);
                    }

                }
            }
        }
    }

    private void render(Circle obj) {
        debug("Circle render");
        if (obj.r != null && !obj.r.isZero()) {
            this.updateStyleForElement(this.state, obj);
            if (this.display()) {
                if (this.visible()) {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    android.graphics.Path path = this.makePathAndBoundingBox(obj);
                    this.updateParentBoundingBox(obj);
                    this.checkForGradiantsAndPatterns(obj);
                    this.checkForClipPath(obj);
                    boolean compositing = this.pushLayer();
                    if (this.state.hasFill) {
                        this.doFilledPath(obj, path);
                    }

                    if (this.state.hasStroke) {
                        this.doStroke(path);
                    }

                    if (compositing) {
                        this.popLayer(obj);
                    }

                }
            }
        }
    }

    private void render(Ellipse obj) {
        debug("Ellipse render");
        if (obj.rx != null && obj.ry != null && !obj.rx.isZero() && !obj.ry.isZero()) {
            this.updateStyleForElement(this.state, obj);
            if (this.display()) {
                if (this.visible()) {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    android.graphics.Path path = this.makePathAndBoundingBox(obj);
                    this.updateParentBoundingBox(obj);
                    this.checkForGradiantsAndPatterns(obj);
                    this.checkForClipPath(obj);
                    boolean compositing = this.pushLayer();
                    if (this.state.hasFill) {
                        this.doFilledPath(obj, path);
                    }

                    if (this.state.hasStroke) {
                        this.doStroke(path);
                    }

                    if (compositing) {
                        this.popLayer(obj);
                    }

                }
            }
        }
    }

    private void render(Line obj) {
        debug("Line render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                if (this.state.hasStroke) {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    android.graphics.Path path = this.makePathAndBoundingBox(obj);
                    this.updateParentBoundingBox(obj);
                    this.checkForGradiantsAndPatterns(obj);
                    this.checkForClipPath(obj);
                    boolean compositing = this.pushLayer();
                    this.doStroke(path);
                    this.renderMarkers(obj);
                    if (compositing) {
                        this.popLayer(obj);
                    }

                }
            }
        }
    }

    private List<SVGAndroidRenderer.MarkerVector> calculateMarkerPositions(Line obj) {
        float _x1 = obj.x1 != null ? obj.x1.floatValueX(this) : 0.0F;
        float _y1 = obj.y1 != null ? obj.y1.floatValueY(this) : 0.0F;
        float _x2 = obj.x2 != null ? obj.x2.floatValueX(this) : 0.0F;
        float _y2 = obj.y2 != null ? obj.y2.floatValueY(this) : 0.0F;
        List<SVGAndroidRenderer.MarkerVector> markers = new ArrayList(2);
        markers.add(new SVGAndroidRenderer.MarkerVector(_x1, _y1, _x2 - _x1, _y2 - _y1));
        markers.add(new SVGAndroidRenderer.MarkerVector(_x2, _y2, _x2 - _x1, _y2 - _y1));
        return markers;
    }

    private void render(PolyLine obj) {
        debug("PolyLine render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                if (this.state.hasStroke || this.state.hasFill) {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    int numPoints = obj.points.length;
                    if (numPoints >= 2) {
                        android.graphics.Path path = this.makePathAndBoundingBox(obj);
                        this.updateParentBoundingBox(obj);
                        this.checkForGradiantsAndPatterns(obj);
                        this.checkForClipPath(obj);
                        boolean compositing = this.pushLayer();
                        if (this.state.hasFill) {
                            this.doFilledPath(obj, path);
                        }

                        if (this.state.hasStroke) {
                            this.doStroke(path);
                        }

                        this.renderMarkers(obj);
                        if (compositing) {
                            this.popLayer(obj);
                        }

                    }
                }
            }
        }
    }

    private List<SVGAndroidRenderer.MarkerVector> calculateMarkerPositions(PolyLine obj) {
        int numPoints = obj.points.length;
        if (numPoints < 2) {
            return null;
        } else {
            List<SVGAndroidRenderer.MarkerVector> markers = new ArrayList();
            SVGAndroidRenderer.MarkerVector lastPos = new SVGAndroidRenderer.MarkerVector(obj.points[0], obj.points[1], 0.0F, 0.0F);
            float x = 0.0F;
            float y = 0.0F;

            for(int i = 2; i < numPoints; i += 2) {
                x = obj.points[i];
                y = obj.points[i + 1];
                lastPos.add(x, y);
                markers.add(lastPos);
                SVGAndroidRenderer.MarkerVector newPos = new SVGAndroidRenderer.MarkerVector(x, y, x - lastPos.x, y - lastPos.y);
                lastPos = newPos;
            }

            if (obj instanceof Polygon) {
                if (x != obj.points[0] && y != obj.points[1]) {
                    x = obj.points[0];
                    y = obj.points[1];
                    lastPos.add(x, y);
                    markers.add(lastPos);
                    SVGAndroidRenderer.MarkerVector newPos = new SVGAndroidRenderer.MarkerVector(x, y, x - lastPos.x, y - lastPos.y);
                    newPos.add((SVGAndroidRenderer.MarkerVector)markers.get(0));
                    markers.add(newPos);
                    markers.set(0, newPos);
                }
            } else {
                markers.add(lastPos);
            }

            return markers;
        }
    }

    private void render(Polygon obj) {
        debug("Polygon render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                if (this.state.hasStroke || this.state.hasFill) {
                    if (obj.transform != null) {
                        this.canvas.concat(obj.transform);
                    }

                    int numPoints = obj.points.length;
                    if (numPoints >= 2) {
                        android.graphics.Path path = this.makePathAndBoundingBox((PolyLine)obj);
                        this.updateParentBoundingBox(obj);
                        this.checkForGradiantsAndPatterns(obj);
                        this.checkForClipPath(obj);
                        boolean compositing = this.pushLayer();
                        if (this.state.hasFill) {
                            this.doFilledPath(obj, path);
                        }

                        if (this.state.hasStroke) {
                            this.doStroke(path);
                        }

                        this.renderMarkers(obj);
                        if (compositing) {
                            this.popLayer(obj);
                        }

                    }
                }
            }
        }
    }

    private void render(Text obj) {
        debug("Text render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (obj.transform != null) {
                this.canvas.concat(obj.transform);
            }

            float x = obj.x != null && obj.x.size() != 0 ? ((Length)obj.x.get(0)).floatValueX(this) : 0.0F;
            float y = obj.y != null && obj.y.size() != 0 ? ((Length)obj.y.get(0)).floatValueY(this) : 0.0F;
            float dx = obj.dx != null && obj.dx.size() != 0 ? ((Length)obj.dx.get(0)).floatValueX(this) : 0.0F;
            float dy = obj.dy != null && obj.dy.size() != 0 ? ((Length)obj.dy.get(0)).floatValueY(this) : 0.0F;
            TextAnchor anchor = this.getAnchorPosition();
            if (anchor != TextAnchor.Start) {
                float textWidth = this.calculateTextWidth(obj);
                if (anchor == TextAnchor.Middle) {
                    x -= textWidth / 2.0F;
                } else {
                    x -= textWidth;
                }
            }

            if (obj.boundingBox == null) {
                SVGAndroidRenderer.TextBoundsCalculator proc = new SVGAndroidRenderer.TextBoundsCalculator(x, y);
                this.enumerateTextSpans(obj, proc);
                obj.boundingBox = new Box(proc.bbox.left, proc.bbox.top, proc.bbox.width(), proc.bbox.height());
            }

            this.updateParentBoundingBox(obj);
            this.checkForGradiantsAndPatterns(obj);
            this.checkForClipPath(obj);
            boolean compositing = this.pushLayer();
            this.enumerateTextSpans(obj, new SVGAndroidRenderer.PlainTextDrawer(x + dx, y + dy));
            if (compositing) {
                this.popLayer(obj);
            }

        }
    }

    private TextAnchor getAnchorPosition() {
        if (this.state.style.direction != TextDirection.LTR && this.state.style.textAnchor != TextAnchor.Middle) {
            return this.state.style.textAnchor == TextAnchor.Start ? TextAnchor.End : TextAnchor.Start;
        } else {
            return this.state.style.textAnchor;
        }
    }

    private void enumerateTextSpans(TextContainer obj, SVGAndroidRenderer.TextProcessor textprocessor) {
        if (this.display()) {
            Iterator<SvgObject> iter = obj.children.iterator();

            for(boolean isFirstChild = true; iter.hasNext(); isFirstChild = false) {
                SvgObject child = (SvgObject)iter.next();
                if (child instanceof TextSequence) {
                    textprocessor.processText(this.textXMLSpaceTransform(((TextSequence)child).text, isFirstChild, !iter.hasNext()));
                } else {
                    this.processTextChild(child, textprocessor);
                }
            }

        }
    }

    private void processTextChild(SvgObject obj, SVGAndroidRenderer.TextProcessor textprocessor) {
        if (textprocessor.doTextContainer((TextContainer)obj)) {
            if (obj instanceof TextPath) {
                this.statePush();
                this.renderTextPath((TextPath)obj);
                this.statePop();
            } else if (obj instanceof TSpan) {
                debug("TSpan render");
                this.statePush();
                TSpan tspan = (TSpan)obj;
                this.updateStyleForElement(this.state, tspan);
                if (this.display()) {
                    float x = 0.0F;
                    float y = 0.0F;
                    float dx = 0.0F;
                    float dy = 0.0F;
                    if (textprocessor instanceof SVGAndroidRenderer.PlainTextDrawer) {
                        x = tspan.x != null && tspan.x.size() != 0 ? ((Length)tspan.x.get(0)).floatValueX(this) : ((SVGAndroidRenderer.PlainTextDrawer)textprocessor).x;
                        y = tspan.y != null && tspan.y.size() != 0 ? ((Length)tspan.y.get(0)).floatValueY(this) : ((SVGAndroidRenderer.PlainTextDrawer)textprocessor).y;
                        dx = tspan.dx != null && tspan.dx.size() != 0 ? ((Length)tspan.dx.get(0)).floatValueX(this) : 0.0F;
                        dy = tspan.dy != null && tspan.dy.size() != 0 ? ((Length)tspan.dy.get(0)).floatValueY(this) : 0.0F;
                    }

                    this.checkForGradiantsAndPatterns((SvgElement)tspan.getTextRoot());
                    if (textprocessor instanceof SVGAndroidRenderer.PlainTextDrawer) {
                        ((SVGAndroidRenderer.PlainTextDrawer)textprocessor).x = x + dx;
                        ((SVGAndroidRenderer.PlainTextDrawer)textprocessor).y = y + dy;
                    }

                    boolean compositing = this.pushLayer();
                    this.enumerateTextSpans(tspan, textprocessor);
                    if (compositing) {
                        this.popLayer(tspan);
                    }
                }

                this.statePop();
            } else if (obj instanceof TRef) {
                this.statePush();
                TRef tref = (TRef)obj;
                this.updateStyleForElement(this.state, tref);
                if (this.display()) {
                    this.checkForGradiantsAndPatterns((SvgElement)tref.getTextRoot());
                    SvgObject ref = obj.document.resolveIRI(tref.href);
                    if (ref != null && ref instanceof TextContainer) {
                        StringBuilder str = new StringBuilder();
                        this.extractRawText((TextContainer)ref, str);
                        if (str.length() > 0) {
                            textprocessor.processText(str.toString());
                        }
                    } else {
                        error("Tref reference '%s' not found", tref.href);
                    }
                }

                this.statePop();
            }

        }
    }

    private void renderTextPath(TextPath obj) {
        debug("TextPath render");
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                SvgObject ref = obj.document.resolveIRI(obj.href);
                if (ref == null) {
                    error("TextPath reference '%s' not found", obj.href);
                } else {
                    Path pathObj = (Path)ref;
                    android.graphics.Path path = (new SVGAndroidRenderer.PathConverter(pathObj.d)).getPath();
                    if (pathObj.transform != null) {
                        path.transform(pathObj.transform);
                    }

                    PathMeasure measure = new PathMeasure(path, false);
                    float startOffset = obj.startOffset != null ? obj.startOffset.floatValue(this, measure.getLength()) : 0.0F;
                    TextAnchor anchor = this.getAnchorPosition();
                    if (anchor != TextAnchor.Start) {
                        float textWidth = this.calculateTextWidth(obj);
                        if (anchor == TextAnchor.Middle) {
                            startOffset -= textWidth / 2.0F;
                        } else {
                            startOffset -= textWidth;
                        }
                    }

                    this.checkForGradiantsAndPatterns((SvgElement)obj.getTextRoot());
                    boolean compositing = this.pushLayer();
                    this.enumerateTextSpans(obj, new SVGAndroidRenderer.PathTextDrawer(path, startOffset, 0.0F));
                    if (compositing) {
                        this.popLayer(obj);
                    }

                }
            }
        }
    }

    private float calculateTextWidth(TextContainer parentTextObj) {
        SVGAndroidRenderer.TextWidthCalculator proc = new SVGAndroidRenderer.TextWidthCalculator((SVGAndroidRenderer.TextWidthCalculator)null);
        this.enumerateTextSpans(parentTextObj, proc);
        return proc.x;
    }

    private void extractRawText(TextContainer parent, StringBuilder str) {
        Iterator<SvgObject> iter = parent.children.iterator();

        for(boolean isFirstChild = true; iter.hasNext(); isFirstChild = false) {
            SvgObject child = (SvgObject)iter.next();
            if (child instanceof TextContainer) {
                this.extractRawText((TextContainer)child, str);
            } else if (child instanceof TextSequence) {
                str.append(this.textXMLSpaceTransform(((TextSequence)child).text, isFirstChild, !iter.hasNext()));
            }
        }

    }

    private String textXMLSpaceTransform(String text, boolean isFirstChild, boolean isLastChild) {
        if (this.state.spacePreserve) {
            return text.replaceAll("[\\n\\t]", " ");
        } else {
            text = text.replaceAll("\\n", "");
            text = text.replaceAll("\\t", " ");
            if (isFirstChild) {
                text = text.replaceAll("^\\s+", "");
            }

            if (isLastChild) {
                text = text.replaceAll("\\s+$", "");
            }

            return text.replaceAll("\\s{2,}", " ");
        }
    }

    private void render(Symbol obj, Length width, Length height) {
        debug("Symbol render");
        if ((width == null || !width.isZero()) && (height == null || !height.isZero())) {
            PreserveAspectRatio positioning = obj.preserveAspectRatio != null ? obj.preserveAspectRatio : PreserveAspectRatio.LETTERBOX;
            this.updateStyleForElement(this.state, obj);
            float _w = width != null ? width.floatValueX(this) : this.state.viewPort.width;
            float _h = height != null ? height.floatValueX(this) : this.state.viewPort.height;
            this.state.viewPort = new Box(0.0F, 0.0F, _w, _h);
            if (!this.state.style.overflow) {
                this.setClipRect(this.state.viewPort.minX, this.state.viewPort.minY, this.state.viewPort.width, this.state.viewPort.height);
            }

            if (obj.viewBox != null) {
                this.canvas.concat(this.calculateViewBoxTransform(this.state.viewPort, obj.viewBox, positioning));
                this.state.viewBox = obj.viewBox;
            }

            boolean compositing = this.pushLayer();
            this.renderChildren(obj, true);
            if (compositing) {
                this.popLayer(obj);
            }

            this.updateParentBoundingBox(obj);
        }
    }

    private void render(Image obj) {
        debug("Image render");
        if (obj.width != null && !obj.width.isZero() && obj.height != null && !obj.height.isZero()) {
            if (obj.href != null) {
                PreserveAspectRatio positioning = obj.preserveAspectRatio != null ? obj.preserveAspectRatio : PreserveAspectRatio.LETTERBOX;
                Bitmap image = this.checkForImageDataURL(obj.href);
                if (image == null) {
                    SVGExternalFileResolver fileResolver = this.document.getFileResolver();
                    if (fileResolver == null) {
                        return;
                    }

                    image = fileResolver.resolveImage(obj.href);
                }

                if (image == null) {
                    error("Could not locate image '%s'", obj.href);
                } else {
                    this.updateStyleForElement(this.state, obj);
                    if (this.display()) {
                        if (this.visible()) {
                            if (obj.transform != null) {
                                this.canvas.concat(obj.transform);
                            }

                            float _x = obj.x != null ? obj.x.floatValueX(this) : 0.0F;
                            float _y = obj.y != null ? obj.y.floatValueY(this) : 0.0F;
                            float _w = obj.width.floatValueX(this);
                            float _h = obj.height.floatValueX(this);
                            this.state.viewPort = new Box(_x, _y, _w, _h);
                            if (!this.state.style.overflow) {
                                this.setClipRect(this.state.viewPort.minX, this.state.viewPort.minY, this.state.viewPort.width, this.state.viewPort.height);
                            }

                            obj.boundingBox = new Box(0.0F, 0.0F, (float)image.getWidth(), (float)image.getHeight());
                            this.canvas.concat(this.calculateViewBoxTransform(this.state.viewPort, obj.boundingBox, positioning));
                            this.updateParentBoundingBox(obj);
                            this.checkForClipPath(obj);
                            boolean compositing = this.pushLayer();
                            this.viewportFill();
                            this.canvas.drawBitmap(image, 0.0F, 0.0F, this.state.fillPaint);
                            if (compositing) {
                                this.popLayer(obj);
                            }

                        }
                    }
                }
            }
        }
    }

    private Bitmap checkForImageDataURL(String url) {
        if (!url.startsWith("data:")) {
            return null;
        } else if (url.length() < 14) {
            return null;
        } else {
            int comma = url.indexOf(44);
            if (comma != -1 && comma >= 12) {
                if (!";base64".equals(url.substring(comma - 7, comma))) {
                    return null;
                } else {
                    byte[] imageData = Base64.decode(url.substring(comma + 1), 0);
                    return BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
                }
            } else {
                return null;
            }
        }
    }

    private boolean display() {
        return this.state.style.display != null ? this.state.style.display : true;
    }

    private boolean visible() {
        return this.state.style.visibility != null ? this.state.style.visibility : true;
    }

    private Matrix calculateViewBoxTransform(Box viewPort, Box viewBox, PreserveAspectRatio positioning) {
        Matrix m = new Matrix();
        if (positioning != null && positioning.getAlignment() != null) {
            float xScale = viewPort.width / viewBox.width;
            float yScale = viewPort.height / viewBox.height;
            float xOffset = -viewBox.minX;
            float yOffset = -viewBox.minY;
            if (positioning.equals(PreserveAspectRatio.STRETCH)) {
                m.preTranslate(viewPort.minX, viewPort.minY);
                m.preScale(xScale, yScale);
                m.preTranslate(xOffset, yOffset);
                return m;
            } else {
                float scale = positioning.getScale() == Scale.Slice ? Math.max(xScale, yScale) : Math.min(xScale, yScale);
                float imageW = viewPort.width / scale;
                float imageH = viewPort.height / scale;
                //$SWITCH_TABLE$com$caverock$androidsvg$PreserveAspectRatio$Alignment()[positioning.getAlignment().ordinal()]
                switch(positioning.getAlignment().ordinal()) {
                    case 3:
                    case 6:
                    case 9:
                        xOffset -= (viewBox.width - imageW) / 2.0F;
                        break;
                    case 4:
                    case 7:
                    case 10:
                        xOffset -= viewBox.width - imageW;
                    case 5:
                    case 8:
                }

                //positioning.getAlignment().ordinal()
                switch(positioning.getAlignment().ordinal()) {
                    case 5:
                    case 6:
                    case 7:
                        yOffset -= (viewBox.height - imageH) / 2.0F;
                        break;
                    case 8:
                    case 9:
                    case 10:
                        yOffset -= viewBox.height - imageH;
                }

                m.preTranslate(viewPort.minX, viewPort.minY);
                m.preScale(scale, scale);
                m.preTranslate(xOffset, yOffset);
                return m;
            }
        } else {
            return m;
        }
    }

    private boolean isSpecified(Style style, long flag) {
        return (style.specifiedFlags & flag) != 0L;
    }

    private void updateStyle(SVGAndroidRenderer.RendererState state, Style style) {
        if (this.isSpecified(style, 4096L)) {
            state.style.color = style.color;
        }

        if (this.isSpecified(style, 2048L)) {
            state.style.opacity = style.opacity;
        }

        if (this.isSpecified(style, 1L)) {
            state.style.fill = style.fill;
            state.hasFill = style.fill != null;
        }

        if (this.isSpecified(style, 4L)) {
            state.style.fillOpacity = style.fillOpacity;
        }

        if (this.isSpecified(style, 6149L)) {
            this.setPaintColour(state, true, state.style.fill);
        }

        if (this.isSpecified(style, 2L)) {
            state.style.fillRule = style.fillRule;
        }

        if (this.isSpecified(style, 8L)) {
            state.style.stroke = style.stroke;
            state.hasStroke = style.stroke != null;
        }

        if (this.isSpecified(style, 16L)) {
            state.style.strokeOpacity = style.strokeOpacity;
        }

        if (this.isSpecified(style, 6168L)) {
            this.setPaintColour(state, false, state.style.stroke);
        }

        if (this.isSpecified(style, 34359738368L)) {
            state.style.vectorEffect = style.vectorEffect;
        }

        if (this.isSpecified(style, 32L)) {
            state.style.strokeWidth = style.strokeWidth;
            state.strokePaint.setStrokeWidth(state.style.strokeWidth.floatValue(this));
        }

        if (this.isSpecified(style, 64L)) {
            state.style.strokeLineCap = style.strokeLineCap;
            //$SWITCH_TABLE$com$caverock$androidsvg$SVG$Style$LineCaps()[style.strokeLineCap.ordinal()]
            switch(style.strokeLineCap.ordinal()) {
                case 1:
                    state.strokePaint.setStrokeCap(Cap.BUTT);
                    break;
                case 2:
                    state.strokePaint.setStrokeCap(Cap.ROUND);
                    break;
                case 3:
                    state.strokePaint.setStrokeCap(Cap.SQUARE);
            }
        }

        if (this.isSpecified(style, 128L)) {
            state.style.strokeLineJoin = style.strokeLineJoin;
            //$SWITCH_TABLE$com$caverock$androidsvg$SVG$Style$LineJoin()[style.strokeLineJoin.ordinal()]
            switch(style.strokeLineJoin.ordinal()) {
                case 1:
                    state.strokePaint.setStrokeJoin(Join.MITER);
                    break;
                case 2:
                    state.strokePaint.setStrokeJoin(Join.ROUND);
                    break;
                case 3:
                    state.strokePaint.setStrokeJoin(Join.BEVEL);
            }
        }

        if (this.isSpecified(style, 256L)) {
            state.style.strokeMiterLimit = style.strokeMiterLimit;
            state.strokePaint.setStrokeMiter(style.strokeMiterLimit);
        }

        if (this.isSpecified(style, 512L)) {
            state.style.strokeDashArray = style.strokeDashArray;
        }

        if (this.isSpecified(style, 1024L)) {
            state.style.strokeDashOffset = style.strokeDashOffset;
        }

        float intervalSum;
        if (this.isSpecified(style, 1536L)) {
            if (state.style.strokeDashArray == null) {
                state.strokePaint.setPathEffect((PathEffect)null);
            } else {
                intervalSum = 0.0F;
                int n = state.style.strokeDashArray.length;
                int arrayLen = n % 2 == 0 ? n : n * 2;
                float[] intervals = new float[arrayLen];

                for(int i = 0; i < arrayLen; ++i) {
                    intervals[i] = state.style.strokeDashArray[i % n].floatValue(this);
                    intervalSum += intervals[i];
                }

                if (intervalSum == 0.0F) {
                    state.strokePaint.setPathEffect((PathEffect)null);
                } else {
                    float offset = state.style.strokeDashOffset.floatValue(this);
                    if (offset < 0.0F) {
                        offset = intervalSum + offset % intervalSum;
                    }

                    state.strokePaint.setPathEffect(new DashPathEffect(intervals, offset));
                }
            }
        }

        if (this.isSpecified(style, 16384L)) {
            intervalSum = this.getCurrentFontSize();
            state.style.fontSize = style.fontSize;
            state.fillPaint.setTextSize(style.fontSize.floatValue(this, intervalSum));
            state.strokePaint.setTextSize(style.fontSize.floatValue(this, intervalSum));
        }

        if (this.isSpecified(style, 8192L)) {
            state.style.fontFamily = style.fontFamily;
        }

        if (this.isSpecified(style, 32768L)) {
            Style var10000;
            if (style.fontWeight == -1 && state.style.fontWeight > 100) {
                var10000 = state.style;
                var10000.fontWeight = var10000.fontWeight - 100;
            } else if (style.fontWeight == 1 && state.style.fontWeight < 900) {
                var10000 = state.style;
                var10000.fontWeight = var10000.fontWeight + 100;
            } else {
                state.style.fontWeight = style.fontWeight;
            }
        }

        if (this.isSpecified(style, 65536L)) {
            state.style.fontStyle = style.fontStyle;
        }

        if (this.isSpecified(style, 106496L)) {
            SVGExternalFileResolver fileResolver = null;
            Typeface font = null;
            if (state.style.fontFamily != null && this.document != null) {
                fileResolver = this.document.getFileResolver();
                Iterator var11 = state.style.fontFamily.iterator();

                while(var11.hasNext()) {
                    String fontName = (String)var11.next();
                    font = this.checkGenericFont(fontName, state.style.fontWeight, state.style.fontStyle);
                    if (font == null && fileResolver != null) {
                        font = fileResolver.resolveFont(fontName, state.style.fontWeight, String.valueOf(state.style.fontStyle));
                    }

                    if (font != null) {
                        break;
                    }
                }
            }

            if (font == null) {
                font = this.checkGenericFont("sans-serif", state.style.fontWeight, state.style.fontStyle);
            }

            state.fillPaint.setTypeface(font);
            state.strokePaint.setTypeface(font);
        }

        if (this.isSpecified(style, 131072L)) {
            state.style.textDecoration = style.textDecoration;
            state.fillPaint.setStrikeThruText(style.textDecoration == TextDecoration.LineThrough);
            state.fillPaint.setUnderlineText(style.textDecoration == TextDecoration.Underline);
            if (VERSION.SDK_INT >= 17) {
                state.strokePaint.setStrikeThruText(style.textDecoration == TextDecoration.LineThrough);
                state.strokePaint.setUnderlineText(style.textDecoration == TextDecoration.Underline);
            }
        }

        if (this.isSpecified(style, 68719476736L)) {
            state.style.direction = style.direction;
        }

        if (this.isSpecified(style, 262144L)) {
            state.style.textAnchor = style.textAnchor;
        }

        if (this.isSpecified(style, 524288L)) {
            state.style.overflow = style.overflow;
        }

        if (this.isSpecified(style, 2097152L)) {
            state.style.markerStart = style.markerStart;
        }

        if (this.isSpecified(style, 4194304L)) {
            state.style.markerMid = style.markerMid;
        }

        if (this.isSpecified(style, 8388608L)) {
            state.style.markerEnd = style.markerEnd;
        }

        if (this.isSpecified(style, 16777216L)) {
            state.style.display = style.display;
        }

        if (this.isSpecified(style, 33554432L)) {
            state.style.visibility = style.visibility;
        }

        if (this.isSpecified(style, 1048576L)) {
            state.style.clip = style.clip;
        }

        if (this.isSpecified(style, 268435456L)) {
            state.style.clipPath = style.clipPath;
        }

        if (this.isSpecified(style, 536870912L)) {
            state.style.clipRule = style.clipRule;
        }

        if (this.isSpecified(style, 1073741824L)) {
            state.style.mask = style.mask;
        }

        if (this.isSpecified(style, 67108864L)) {
            state.style.stopColor = style.stopColor;
        }

        if (this.isSpecified(style, 134217728L)) {
            state.style.stopOpacity = style.stopOpacity;
        }

        if (this.isSpecified(style, 8589934592L)) {
            state.style.viewportFill = style.viewportFill;
        }

        if (this.isSpecified(style, 17179869184L)) {
            state.style.viewportFillOpacity = style.viewportFillOpacity;
        }

    }

    private void setPaintColour(SVGAndroidRenderer.RendererState state, boolean isFill, SvgPaint paint) {
        float paintOpacity = isFill ? state.style.fillOpacity : state.style.strokeOpacity;
        int col;
        if (paint instanceof Colour) {
            col = ((Colour)paint).colour;
        } else {
            if (!(paint instanceof CurrentColor)) {
                return;
            }

            col = state.style.color.colour;
        }

        col |= this.clamp255(paintOpacity) << 24;
        if (isFill) {
            state.fillPaint.setColor(col);
        } else {
            state.strokePaint.setColor(col);
        }

    }

    @SuppressLint("WrongConstant")
    private Typeface checkGenericFont(String fontName, Integer fontWeight, FontStyle fontStyle) {
        Typeface font = null;
        boolean italic = fontStyle == FontStyle.Italic;
        int typefaceStyle = fontWeight > 500 ? (italic ? 3 : 1) : (italic ? 2 : 0);
        if (fontName.equals("serif")) {
            font = Typeface.create(Typeface.SERIF, typefaceStyle);
        } else if (fontName.equals("sans-serif")) {
            font = Typeface.create(Typeface.SANS_SERIF, typefaceStyle);
        } else if (fontName.equals("monospace")) {
            font = Typeface.create(Typeface.MONOSPACE, typefaceStyle);
        } else if (fontName.equals("cursive")) {
            font = Typeface.create(Typeface.SANS_SERIF, typefaceStyle);
        } else if (fontName.equals("fantasy")) {
            font = Typeface.create(Typeface.SANS_SERIF, typefaceStyle);
        }

        return font;
    }

    private int clamp255(float val) {
        int i = (int)(val * 256.0F);
        return i < 0 ? 0 : (i > 255 ? 255 : i);
    }

    private FillType getFillTypeFromState() {
        if (this.state.style.fillRule == null) {
            return FillType.WINDING;
        } else {
            //$SWITCH_TABLE$com$caverock$androidsvg$SVG$Style$FillRule()[this.state.style.fillRule.ordinal()]
            switch(this.state.style.fillRule.ordinal()) {
                case 1:
                default:
                    return FillType.WINDING;
                case 2:
                    return FillType.EVEN_ODD;
            }
        }
    }

    private void setClipRect(float minX, float minY, float width, float height) {
        float left = minX;
        float top = minY;
        float right = minX + width;
        float bottom = minY + height;
        if (this.state.style.clip != null) {
            left = minX + this.state.style.clip.left.floatValueX(this);
            top = minY + this.state.style.clip.top.floatValueY(this);
            right -= this.state.style.clip.right.floatValueX(this);
            bottom -= this.state.style.clip.bottom.floatValueY(this);
        }

        this.canvas.clipRect(left, top, right, bottom);
    }

    private void viewportFill() {
        int col;
        if (this.state.style.viewportFill instanceof Colour) {
            col = ((Colour)this.state.style.viewportFill).colour;
        } else {
            if (!(this.state.style.viewportFill instanceof CurrentColor)) {
                return;
            }

            col = this.state.style.color.colour;
        }

        if (this.state.style.viewportFillOpacity != null) {
            col |= this.clamp255(this.state.style.viewportFillOpacity) << 24;
        }

        this.canvas.drawColor(col);
    }

    private static void arcTo(float lastX, float lastY, float rx, float ry, float angle, boolean largeArcFlag, boolean sweepFlag, float x, float y, PathInterface pather) {
        if (lastX != x || lastY != y) {
            if (rx != 0.0F && ry != 0.0F) {
                rx = Math.abs(rx);
                ry = Math.abs(ry);
                float angleRad = (float)Math.toRadians((double)angle % 360.0D);
                double cosAngle = Math.cos((double)angleRad);
                double sinAngle = Math.sin((double)angleRad);
                double dx2 = (double)(lastX - x) / 2.0D;
                double dy2 = (double)(lastY - y) / 2.0D;
                double x1 = cosAngle * dx2 + sinAngle * dy2;
                double y1 = -sinAngle * dx2 + cosAngle * dy2;
                double rx_sq = (double)(rx * rx);
                double ry_sq = (double)(ry * ry);
                double x1_sq = x1 * x1;
                double y1_sq = y1 * y1;
                double radiiCheck = x1_sq / rx_sq + y1_sq / ry_sq;
                if (radiiCheck > 1.0D) {
                    rx = (float)Math.sqrt(radiiCheck) * rx;
                    ry = (float)Math.sqrt(radiiCheck) * ry;
                    rx_sq = (double)(rx * rx);
                    ry_sq = (double)(ry * ry);
                }

                double sign = (double)(largeArcFlag == sweepFlag ? -1 : 1);
                double sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq);
                sq = sq < 0.0D ? 0.0D : sq;
                double coef = sign * Math.sqrt(sq);
                double cx1 = coef * ((double)rx * y1 / (double)ry);
                double cy1 = coef * -((double)ry * x1 / (double)rx);
                double sx2 = (double)(lastX + x) / 2.0D;
                double sy2 = (double)(lastY + y) / 2.0D;
                double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1);
                double cy = sy2 + sinAngle * cx1 + cosAngle * cy1;
                double ux = (x1 - cx1) / (double)rx;
                double uy = (y1 - cy1) / (double)ry;
                double vx = (-x1 - cx1) / (double)rx;
                double vy = (-y1 - cy1) / (double)ry;
                double n = Math.sqrt(ux * ux + uy * uy);
                sign = uy < 0.0D ? -1.0D : 1.0D;
                double angleStart = Math.toDegrees(sign * Math.acos(ux / n));
                n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
                double p = ux * vx + uy * vy;
                sign = ux * vy - uy * vx < 0.0D ? -1.0D : 1.0D;
                double angleExtent = Math.toDegrees(sign * Math.acos(p / n));
                if (!sweepFlag && angleExtent > 0.0D) {
                    angleExtent -= 360.0D;
                } else if (sweepFlag && angleExtent < 0.0D) {
                    angleExtent += 360.0D;
                }

                angleExtent %= 360.0D;
                angleStart %= 360.0D;
                float[] bezierPoints = arcToBeziers(angleStart, angleExtent);
                Matrix m = new Matrix();
                m.postScale(rx, ry);
                m.postRotate(angle);
                m.postTranslate((float)cx, (float)cy);
                m.mapPoints(bezierPoints);
                bezierPoints[bezierPoints.length - 2] = x;
                bezierPoints[bezierPoints.length - 1] = y;

                for(int i = 0; i < bezierPoints.length; i += 6) {
                    pather.cubicTo(bezierPoints[i], bezierPoints[i + 1], bezierPoints[i + 2], bezierPoints[i + 3], bezierPoints[i + 4], bezierPoints[i + 5]);
                }

            } else {
                pather.lineTo(x, y);
            }
        }
    }

    private static float[] arcToBeziers(double angleStart, double angleExtent) {
        int numSegments = (int)Math.ceil(Math.abs(angleExtent) / 90.0D);
        angleStart = Math.toRadians(angleStart);
        angleExtent = Math.toRadians(angleExtent);
        float angleIncrement = (float)(angleExtent / (double)numSegments);
        double controlLength = 1.3333333333333333D * Math.sin((double)angleIncrement / 2.0D) / (1.0D + Math.cos((double)angleIncrement / 2.0D));
        float[] coords = new float[numSegments * 6];
        int pos = 0;

        for(int i = 0; i < numSegments; ++i) {
            double angle = angleStart + (double)((float)i * angleIncrement);
            double dx = Math.cos(angle);
            double dy = Math.sin(angle);
            coords[pos++] = (float)(dx - controlLength * dy);
            coords[pos++] = (float)(dy + controlLength * dx);
            angle += (double)angleIncrement;
            dx = Math.cos(angle);
            dy = Math.sin(angle);
            coords[pos++] = (float)(dx + controlLength * dy);
            coords[pos++] = (float)(dy - controlLength * dx);
            coords[pos++] = (float)dx;
            coords[pos++] = (float)dy;
        }

        return coords;
    }

    private void renderMarkers(GraphicsElement obj) {
        if (this.state.style.markerStart != null || this.state.style.markerMid != null || this.state.style.markerEnd != null) {
            Marker _markerStart = null;
            Marker _markerMid = null;
            Marker _markerEnd = null;
            SvgObject ref;
            if (this.state.style.markerStart != null) {
                ref = obj.document.resolveIRI(this.state.style.markerStart);
                if (ref != null) {
                    _markerStart = (Marker)ref;
                } else {
                    error("Marker reference '%s' not found", this.state.style.markerStart);
                }
            }

            if (this.state.style.markerMid != null) {
                ref = obj.document.resolveIRI(this.state.style.markerMid);
                if (ref != null) {
                    _markerMid = (Marker)ref;
                } else {
                    error("Marker reference '%s' not found", this.state.style.markerMid);
                }
            }

            if (this.state.style.markerEnd != null) {
                ref = obj.document.resolveIRI(this.state.style.markerEnd);
                if (ref != null) {
                    _markerEnd = (Marker)ref;
                } else {
                    error("Marker reference '%s' not found", this.state.style.markerEnd);
                }
            }

            ref = null;
            List markers;
            if (obj instanceof Path) {
                markers = (new SVGAndroidRenderer.MarkerPositionCalculator(((Path)obj).d)).getMarkers();
            } else if (obj instanceof Line) {
                markers = this.calculateMarkerPositions((Line)obj);
            } else {
                markers = this.calculateMarkerPositions((PolyLine)obj);
            }

            if (markers != null) {
                int markerCount = markers.size();
                if (markerCount != 0) {
                    this.state.style.markerStart = this.state.style.markerMid = this.state.style.markerEnd = null;
                    if (_markerStart != null) {
                        this.renderMarker(_markerStart, (SVGAndroidRenderer.MarkerVector)markers.get(0));
                    }

                    if (_markerMid != null) {
                        for(int i = 1; i < markerCount - 1; ++i) {
                            this.renderMarker(_markerMid, (SVGAndroidRenderer.MarkerVector)markers.get(i));
                        }
                    }

                    if (_markerEnd != null) {
                        this.renderMarker(_markerEnd, (SVGAndroidRenderer.MarkerVector)markers.get(markerCount - 1));
                    }

                }
            }
        }
    }

    private void renderMarker(Marker marker, SVGAndroidRenderer.MarkerVector pos) {
        float angle = 0.0F;
        this.statePush();
        if (marker!=null) {
            if (Float.isNaN((float) marker.orient)) {
                if (pos.dx != 0.0F || pos.dy != 0.0F) {
                    angle = (float)Math.toDegrees(Math.atan2((double)pos.dy, (double)pos.dx));
                }
            } else {
                angle = (float) marker.orient;
            }
        }

        float unitsScale = marker.markerUnitsAreUser ? 1.0F : this.state.style.strokeWidth.floatValue(this.dpi);
        this.state = this.findInheritFromAncestorState(marker);
        Matrix m = new Matrix();
        m.preTranslate(pos.x, pos.y);
        m.preRotate(angle);
        m.preScale(unitsScale, unitsScale);
        float _refX = marker.refX != null ? marker.refX.floatValueX(this) : 0.0F;
        float _refY = marker.refY != null ? marker.refY.floatValueY(this) : 0.0F;
        float _markerWidth = marker.markerWidth != null ? marker.markerWidth.floatValueX(this) : 3.0F;
        float _markerHeight = marker.markerHeight != null ? marker.markerHeight.floatValueY(this) : 3.0F;
        if (marker.viewBox != null) {
            float xScale = _markerWidth / marker.viewBox.width;
            float yScale = _markerHeight / marker.viewBox.height;
            PreserveAspectRatio positioning = marker.preserveAspectRatio != null ? marker.preserveAspectRatio : PreserveAspectRatio.LETTERBOX;
            float imageW;
            if (!positioning.equals(PreserveAspectRatio.STRETCH)) {
                imageW = positioning.getScale() == Scale.Slice ? Math.max(xScale, yScale) : Math.min(xScale, yScale);
                yScale = imageW;
                xScale = imageW;
            }

            m.preTranslate(-_refX * xScale, -_refY * yScale);
            this.canvas.concat(m);
            imageW = marker.viewBox.width * xScale;
            float imageH = marker.viewBox.height * yScale;
            float xOffset = 0.0F;
            float yOffset = 0.0F;
            //$SWITCH_TABLE$com$caverock$androidsvg$PreserveAspectRatio$Alignment()[positioning.getAlignment().ordinal()]
            switch(positioning.getAlignment().ordinal()) {
                case 3:
                case 6:
                case 9:
                    xOffset -= (_markerWidth - imageW) / 2.0F;
                    break;
                case 4:
                case 7:
                case 10:
                    xOffset -= _markerWidth - imageW;
                case 5:
                case 8:
            }

            //$SWITCH_TABLE$com$caverock$androidsvg$PreserveAspectRatio$Alignment()[positioning.getAlignment().ordinal()]
            switch(positioning.getAlignment().ordinal()) {
                case 5:
                case 6:
                case 7:
                    yOffset -= (_markerHeight - imageH) / 2.0F;
                    break;
                case 8:
                case 9:
                case 10:
                    yOffset -= _markerHeight - imageH;
            }

            if (!this.state.style.overflow) {
                this.setClipRect(xOffset, yOffset, _markerWidth, _markerHeight);
            }

            m.reset();
            m.preScale(xScale, yScale);
            this.canvas.concat(m);
        } else {
            m.preTranslate(-_refX, -_refY);
            this.canvas.concat(m);
            if (!this.state.style.overflow) {
                this.setClipRect(0.0F, 0.0F, _markerWidth, _markerHeight);
            }
        }

        boolean compositing = this.pushLayer();
        this.renderChildren(marker, false);
        if (compositing) {
            this.popLayer(marker);
        }

        this.statePop();
    }

    private SVGAndroidRenderer.RendererState findInheritFromAncestorState(SvgObject obj) {
        SVGAndroidRenderer.RendererState newState = new SVGAndroidRenderer.RendererState();
        this.updateStyle(newState, Style.getDefaultStyle());
        return this.findInheritFromAncestorState(obj, newState);
    }

    private SVGAndroidRenderer.RendererState findInheritFromAncestorState(SvgObject obj, SVGAndroidRenderer.RendererState newState) {
        ArrayList ancestors = new ArrayList();

        while(true) {
            if (obj instanceof SvgElementBase) {
                ancestors.add(0, (SvgElementBase)obj);
            }

            if (obj.parent == null) {
                Iterator var5 = ancestors.iterator();

                while(var5.hasNext()) {
                    SvgElementBase ancestor = (SvgElementBase)var5.next();
                    this.updateStyleForElement(newState, ancestor);
                }

                newState.viewBox = this.document.getRootElement().viewBox;
                if (newState.viewBox == null) {
                    newState.viewBox = this.canvasViewPort;
                }

                newState.viewPort = this.canvasViewPort;
                newState.directRendering = this.state.directRendering;
                return newState;
            }

            obj = (SvgObject)obj.parent;
        }
    }

    private void checkForGradiantsAndPatterns(SvgElement obj) {
        if (this.state.style.fill instanceof PaintReference) {
            this.decodePaintReference(true, obj.boundingBox, (PaintReference)this.state.style.fill);
        }

        if (this.state.style.stroke instanceof PaintReference) {
            this.decodePaintReference(false, obj.boundingBox, (PaintReference)this.state.style.stroke);
        }

    }

    private void decodePaintReference(boolean isFill, Box boundingBox, PaintReference paintref) {
        SvgObject ref = this.document.resolveIRI(paintref.href);
        if (ref == null) {
            error("%s reference '%s' not found", isFill ? "Fill" : "Stroke", paintref.href);
            if (paintref.fallback != null) {
                this.setPaintColour(this.state, isFill, paintref.fallback);
            } else if (isFill) {
                this.state.hasFill = false;
            } else {
                this.state.hasStroke = false;
            }

        } else {
            if (ref instanceof SvgLinearGradient) {
                this.makeLinearGradiant(isFill, boundingBox, (SvgLinearGradient)ref);
            }

            if (ref instanceof SvgRadialGradient) {
                this.makeRadialGradiant(isFill, boundingBox, (SvgRadialGradient)ref);
            }

            if (ref instanceof SolidColor) {
                this.setSolidColor(isFill, (SolidColor)ref);
            }

        }
    }

    private void makeLinearGradiant(boolean isFill, Box boundingBox, SvgLinearGradient gradient) {
        if (gradient.href != null) {
            this.fillInChainedGradientFields((GradientElement)gradient, (String)gradient.href);
        }

        boolean userUnits = gradient.gradientUnitsAreUser != null && gradient.gradientUnitsAreUser;
        Paint paint = isFill ? this.state.fillPaint : this.state.strokePaint;
        float _x1;
        float _y1;
        float _x2;
        float _y2;
        if (userUnits) {
            Box viewPortUser = this.getCurrentViewPortInUserUnits();
            _x1 = gradient.x1 != null ? gradient.x1.floatValueX(this) : 0.0F;
            _y1 = gradient.y1 != null ? gradient.y1.floatValueY(this) : 0.0F;
            _x2 = gradient.x2 != null ? gradient.x2.floatValueX(this) : viewPortUser.width;
            _y2 = gradient.y2 != null ? gradient.y2.floatValueY(this) : 0.0F;
        } else {
            _x1 = gradient.x1 != null ? gradient.x1.floatValue(this, 1.0F) : 0.0F;
            _y1 = gradient.y1 != null ? gradient.y1.floatValue(this, 1.0F) : 0.0F;
            _x2 = gradient.x2 != null ? gradient.x2.floatValue(this, 1.0F) : 1.0F;
            _y2 = gradient.y2 != null ? gradient.y2.floatValue(this, 1.0F) : 0.0F;
        }

        this.statePush();
        this.state = this.findInheritFromAncestorState(gradient);
        Matrix m = new Matrix();
        if (!userUnits) {
            m.preTranslate(boundingBox.minX, boundingBox.minY);
            m.preScale(boundingBox.width, boundingBox.height);
        }

        if (gradient.gradientTransform != null) {
            m.preConcat(gradient.gradientTransform);
        }

        int numStops = gradient.children.size();
        if (numStops == 0) {
            this.statePop();
            if (isFill) {
                this.state.hasFill = false;
            } else {
                this.state.hasStroke = false;
            }

        } else {
            int[] colours = new int[numStops];
            float[] positions = new float[numStops];
            int i = 0;
            float lastOffset = -1.0F;
            Iterator var17 = gradient.children.iterator();

            while(var17.hasNext()) {
                SvgObject child = (SvgObject)var17.next();
                Stop stop = (Stop)child;
                if (i != 0 && stop.offset < lastOffset) {
                    positions[i] = lastOffset;
                } else {
                    positions[i] = stop.offset;
                    lastOffset = stop.offset;
                }

                this.statePush();
                this.updateStyleForElement(this.state, stop);
                Colour col = (Colour)this.state.style.stopColor;
                if (col == null) {
                    col = Colour.BLACK;
                }

                colours[i] = this.clamp255(this.state.style.stopOpacity) << 24 | col.colour;
                ++i;
                this.statePop();
            }

            if ((_x1 != _x2 || _y1 != _y2) && numStops != 1) {
                TileMode tileMode = TileMode.CLAMP;
                if (gradient.spreadMethod != null) {
                    if (gradient.spreadMethod == GradientSpread.reflect) {
                        tileMode = TileMode.MIRROR;
                    } else if (gradient.spreadMethod == GradientSpread.repeat) {
                        tileMode = TileMode.REPEAT;
                    }
                }

                this.statePop();
                LinearGradient gr = new LinearGradient(_x1, _y1, _x2, _y2, colours, positions, tileMode);
                gr.setLocalMatrix(m);
                paint.setShader(gr);
            } else {
                this.statePop();
                paint.setColor(colours[numStops - 1]);
            }
        }
    }

    private void makeRadialGradiant(boolean isFill, Box boundingBox, SvgRadialGradient gradient) {
        if (gradient.href != null) {
            this.fillInChainedGradientFields((GradientElement)gradient, (String)gradient.href);
        }

        boolean userUnits = gradient.gradientUnitsAreUser != null && gradient.gradientUnitsAreUser;
        Paint paint = isFill ? this.state.fillPaint : this.state.strokePaint;
        float _cx;
        float _cy;
        float _r;
        if (userUnits) {
            Length fiftyPercent = new Length(50.0F, Unit.percent);
            _cx = gradient.cx != null ? gradient.cx.floatValueX(this) : fiftyPercent.floatValueX(this);
            _cy = gradient.cy != null ? gradient.cy.floatValueY(this) : fiftyPercent.floatValueY(this);
            _r = gradient.r != null ? gradient.r.floatValue(this) : fiftyPercent.floatValue(this);
        } else {
            _cx = gradient.cx != null ? gradient.cx.floatValue(this, 1.0F) : 0.5F;
            _cy = gradient.cy != null ? gradient.cy.floatValue(this, 1.0F) : 0.5F;
            _r = gradient.r != null ? gradient.r.floatValue(this, 1.0F) : 0.5F;
        }

        this.statePush();
        this.state = this.findInheritFromAncestorState(gradient);
        Matrix m = new Matrix();
        if (!userUnits) {
            m.preTranslate(boundingBox.minX, boundingBox.minY);
            m.preScale(boundingBox.width, boundingBox.height);
        }

        if (gradient.gradientTransform != null) {
            m.preConcat(gradient.gradientTransform);
        }

        int numStops = gradient.children.size();
        if (numStops == 0) {
            this.statePop();
            if (isFill) {
                this.state.hasFill = false;
            } else {
                this.state.hasStroke = false;
            }

        } else {
            int[] colours = new int[numStops];
            float[] positions = new float[numStops];
            int i = 0;
            float lastOffset = -1.0F;
            Iterator var16 = gradient.children.iterator();

            while(var16.hasNext()) {
                SvgObject child = (SvgObject)var16.next();
                Stop stop = (Stop)child;
                if (i != 0 && stop.offset < lastOffset) {
                    positions[i] = lastOffset;
                } else {
                    positions[i] = stop.offset;
                    lastOffset = stop.offset;
                }

                this.statePush();
                this.updateStyleForElement(this.state, stop);
                Colour col = (Colour)this.state.style.stopColor;
                if (col == null) {
                    col = Colour.BLACK;
                }

                colours[i] = this.clamp255(this.state.style.stopOpacity) << 24 | col.colour;
                ++i;
                this.statePop();
            }

            if (_r != 0.0F && numStops != 1) {
                TileMode tileMode = TileMode.CLAMP;
                if (gradient.spreadMethod != null) {
                    if (gradient.spreadMethod == GradientSpread.reflect) {
                        tileMode = TileMode.MIRROR;
                    } else if (gradient.spreadMethod == GradientSpread.repeat) {
                        tileMode = TileMode.REPEAT;
                    }
                }

                this.statePop();
                RadialGradient gr = new RadialGradient(_cx, _cy, _r, colours, positions, tileMode);
                gr.setLocalMatrix(m);
                paint.setShader(gr);
            } else {
                this.statePop();
                paint.setColor(colours[numStops - 1]);
            }
        }
    }

    private void fillInChainedGradientFields(GradientElement gradient, String href) {
        SvgObject ref = gradient.document.resolveIRI(href);
        if (ref == null) {
            warn("Gradient reference '%s' not found", href);
        } else if (!(ref instanceof GradientElement)) {
            error("Gradient href attributes must point to other gradient elements");
        } else if (ref == gradient) {
            error("Circular reference in gradient href attribute '%s'", href);
        } else {
            GradientElement grRef = (GradientElement)ref;
            if (gradient.gradientUnitsAreUser == null) {
                gradient.gradientUnitsAreUser = grRef.gradientUnitsAreUser;
            }

            if (gradient.gradientTransform == null) {
                gradient.gradientTransform = grRef.gradientTransform;
            }

            if (gradient.spreadMethod == null) {
                gradient.spreadMethod = grRef.spreadMethod;
            }

            if (gradient.children.isEmpty()) {
                gradient.children = grRef.children;
            }

            try {
                if (gradient instanceof SvgLinearGradient) {
                    this.fillInChainedGradientFields((SvgLinearGradient)gradient, (SvgLinearGradient)ref);
                } else {
                    this.fillInChainedGradientFields((SvgRadialGradient)gradient, (SvgRadialGradient)ref);
                }
            } catch (ClassCastException var6) {
            }

            if (grRef.href != null) {
                this.fillInChainedGradientFields(gradient, grRef.href);
            }

        }
    }

    private void fillInChainedGradientFields(SvgLinearGradient gradient, SvgLinearGradient grRef) {
        if (gradient.x1 == null) {
            gradient.x1 = grRef.x1;
        }

        if (gradient.y1 == null) {
            gradient.y1 = grRef.y1;
        }

        if (gradient.x2 == null) {
            gradient.x2 = grRef.x2;
        }

        if (gradient.y2 == null) {
            gradient.y2 = grRef.y2;
        }

    }

    private void fillInChainedGradientFields(SvgRadialGradient gradient, SvgRadialGradient grRef) {
        if (gradient.cx == null) {
            gradient.cx = grRef.cx;
        }

        if (gradient.cy == null) {
            gradient.cy = grRef.cy;
        }

        if (gradient.r == null) {
            gradient.r = grRef.r;
        }

        if (gradient.fx == null) {
            gradient.fx = grRef.fx;
        }

        if (gradient.fy == null) {
            gradient.fy = grRef.fy;
        }

    }

    private void setSolidColor(boolean isFill, SolidColor ref) {
        if (isFill) {
            if (this.isSpecified(ref.baseStyle, 2147483648L)) {
                this.state.style.fill = ref.baseStyle.solidColor;
                this.state.hasFill = ref.baseStyle.solidColor != null;
            }

            if (this.isSpecified(ref.baseStyle, 4294967296L)) {
                this.state.style.fillOpacity = ref.baseStyle.solidOpacity;
            }

            if (this.isSpecified(ref.baseStyle, 6442450944L)) {
                this.setPaintColour(this.state, isFill, this.state.style.fill);
            }
        } else {
            if (this.isSpecified(ref.baseStyle, 2147483648L)) {
                this.state.style.stroke = ref.baseStyle.solidColor;
                this.state.hasStroke = ref.baseStyle.solidColor != null;
            }

            if (this.isSpecified(ref.baseStyle, 4294967296L)) {
                this.state.style.strokeOpacity = ref.baseStyle.solidOpacity;
            }

            if (this.isSpecified(ref.baseStyle, 6442450944L)) {
                this.setPaintColour(this.state, isFill, this.state.style.stroke);
            }
        }

    }

    private void checkForClipPath(SvgElement obj) {
        this.checkForClipPath(obj, obj.boundingBox);
    }

    private void checkForClipPath(SvgElement obj, Box boundingBox) {
        if (this.state.style.clipPath != null) {
            SvgObject ref = obj.document.resolveIRI(this.state.style.clipPath);
            if (ref == null) {
                error("ClipPath reference '%s' not found", this.state.style.clipPath);
            } else {
                ClipPath clipPath = (ClipPath)ref;
                if (clipPath.children.isEmpty()) {
                    this.canvas.clipRect(0, 0, 0, 0);
                } else {
                    boolean userUnits = clipPath.clipPathUnitsAreUser == null || clipPath.clipPathUnitsAreUser;
                    if (obj instanceof Group && !userUnits) {
                        warn("<clipPath clipPathUnits=\"objectBoundingBox\"> is not supported when referenced from container elements (like %s)", obj.getClass().getSimpleName());
                    } else {
                        this.clipStatePush();
                        if (!userUnits) {
                            Matrix m = new Matrix();
                            m.preTranslate(boundingBox.minX, boundingBox.minY);
                            m.preScale(boundingBox.width, boundingBox.height);
                            this.canvas.concat(m);
                        }

                        if (clipPath.transform != null) {
                            this.canvas.concat(clipPath.transform);
                        }

                        this.state = this.findInheritFromAncestorState(clipPath);
                        this.checkForClipPath(clipPath);
                        android.graphics.Path combinedPath = new android.graphics.Path();
                        Iterator var8 = clipPath.children.iterator();

                        while(var8.hasNext()) {
                            SvgObject child = (SvgObject)var8.next();
                            this.addObjectToClip(child, true, combinedPath, new Matrix());
                        }

                        this.canvas.clipPath(combinedPath);
                        this.clipStatePop();
                    }
                }
            }
        }
    }

    private void addObjectToClip(SvgObject obj, boolean allowUse, android.graphics.Path combinedPath, Matrix combinedPathMatrix) {
        if (this.display()) {
            this.clipStatePush();
            if (obj instanceof Use) {
                if (allowUse) {
                    this.addObjectToClip((Use)obj, combinedPath, combinedPathMatrix);
                } else {
                    error("<use> elements inside a <clipPath> cannot reference another <use>");
                }
            } else if (obj instanceof Path) {
                this.addObjectToClip((Path)obj, combinedPath, combinedPathMatrix);
            } else if (obj instanceof Text) {
                this.addObjectToClip((Text)obj, combinedPath, combinedPathMatrix);
            } else if (obj instanceof GraphicsElement) {
                this.addObjectToClip((GraphicsElement)obj, combinedPath, combinedPathMatrix);
            } else {
                error("Invalid %s element found in clipPath definition", obj.getClass().getSimpleName());
            }

            this.clipStatePop();
        }
    }

    private void clipStatePush() {
        this.canvas.save();
        this.stateStack.push(this.state);
        this.state = (SVGAndroidRenderer.RendererState)this.state.clone();
    }

    private void clipStatePop() {
        this.canvas.restore();
        this.state = (SVGAndroidRenderer.RendererState)this.stateStack.pop();
    }

    private FillType getClipRuleFromState() {
        if (this.state.style.clipRule == null) {
            return FillType.WINDING;
        } else {
            //$SWITCH_TABLE$com$caverock$androidsvg$SVG$Style$FillRule()[this.state.style.clipRule.ordinal()]
            switch(this.state.style.clipRule.ordinal()) {
                case 1:
                default:
                    return FillType.WINDING;
                case 2:
                    return FillType.EVEN_ODD;
            }
        }
    }

    private void addObjectToClip(Path obj, android.graphics.Path combinedPath, Matrix combinedPathMatrix) {
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                if (obj.transform != null) {
                    combinedPathMatrix.preConcat(obj.transform);
                }

                android.graphics.Path path = (new SVGAndroidRenderer.PathConverter(obj.d)).getPath();
                if (obj.boundingBox == null) {
                    obj.boundingBox = this.calculatePathBounds(path);
                }

                this.checkForClipPath(obj);
                combinedPath.setFillType(this.getClipRuleFromState());
                combinedPath.addPath(path, combinedPathMatrix);
            }
        }
    }

    private void addObjectToClip(GraphicsElement obj, android.graphics.Path combinedPath, Matrix combinedPathMatrix) {
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                if (obj.transform != null) {
                    combinedPathMatrix.preConcat(obj.transform);
                }

                android.graphics.Path path;
                if (obj instanceof Rect) {
                    path = this.makePathAndBoundingBox((Rect)obj);
                } else if (obj instanceof Circle) {
                    path = this.makePathAndBoundingBox((Circle)obj);
                } else if (obj instanceof Ellipse) {
                    path = this.makePathAndBoundingBox((Ellipse)obj);
                } else {
                    if (!(obj instanceof PolyLine)) {
                        return;
                    }

                    path = this.makePathAndBoundingBox((PolyLine)obj);
                }

                this.checkForClipPath(obj);
                combinedPath.setFillType(path.getFillType());
                combinedPath.addPath(path, combinedPathMatrix);
            }
        }
    }

    private void addObjectToClip(Use obj, android.graphics.Path combinedPath, Matrix combinedPathMatrix) {
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (this.visible()) {
                if (obj.transform != null) {
                    combinedPathMatrix.preConcat(obj.transform);
                }

                SvgObject ref = obj.document.resolveIRI(obj.href);
                if (ref == null) {
                    error("Use reference '%s' not found", obj.href);
                } else {
                    this.checkForClipPath(obj);
                    this.addObjectToClip(ref, false, combinedPath, combinedPathMatrix);
                }
            }
        }
    }

    private void addObjectToClip(Text obj, android.graphics.Path combinedPath, Matrix combinedPathMatrix) {
        this.updateStyleForElement(this.state, obj);
        if (this.display()) {
            if (obj.transform != null) {
                combinedPathMatrix.preConcat(obj.transform);
            }

            float x = obj.x != null && obj.x.size() != 0 ? ((Length)obj.x.get(0)).floatValueX(this) : 0.0F;
            float y = obj.y != null && obj.y.size() != 0 ? ((Length)obj.y.get(0)).floatValueY(this) : 0.0F;
            float dx = obj.dx != null && obj.dx.size() != 0 ? ((Length)obj.dx.get(0)).floatValueX(this) : 0.0F;
            float dy = obj.dy != null && obj.dy.size() != 0 ? ((Length)obj.dy.get(0)).floatValueY(this) : 0.0F;
            if (this.state.style.textAnchor != TextAnchor.Start) {
                float textWidth = this.calculateTextWidth(obj);
                if (this.state.style.textAnchor == TextAnchor.Middle) {
                    x -= textWidth / 2.0F;
                } else {
                    x -= textWidth;
                }
            }

            if (obj.boundingBox == null) {
                SVGAndroidRenderer.TextBoundsCalculator proc = new SVGAndroidRenderer.TextBoundsCalculator(x, y);
                this.enumerateTextSpans(obj, proc);
                obj.boundingBox = new Box(proc.bbox.left, proc.bbox.top, proc.bbox.width(), proc.bbox.height());
            }

            this.checkForClipPath(obj);
            android.graphics.Path textAsPath = new android.graphics.Path();
            this.enumerateTextSpans(obj, new SVGAndroidRenderer.PlainTextToPath(x + dx, y + dy, textAsPath));
            combinedPath.setFillType(this.getClipRuleFromState());
            combinedPath.addPath(textAsPath, combinedPathMatrix);
        }
    }

    private android.graphics.Path makePathAndBoundingBox(Line obj) {
        float x1 = obj.x1 == null ? 0.0F : obj.x1.floatValueX(this);
        float y1 = obj.y1 == null ? 0.0F : obj.y1.floatValueY(this);
        float x2 = obj.x2 == null ? 0.0F : obj.x2.floatValueX(this);
        float y2 = obj.y2 == null ? 0.0F : obj.y2.floatValueY(this);
        if (obj.boundingBox == null) {
            obj.boundingBox = new Box(Math.min(x1, y1), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
        }

        android.graphics.Path p = new android.graphics.Path();
        p.moveTo(x1, y1);
        p.lineTo(x2, y2);
        return p;
    }

    private android.graphics.Path makePathAndBoundingBox(Rect obj) {
        float rx;
        float ry;
        if (obj.rx == null && obj.ry == null) {
            rx = 0.0F;
            ry = 0.0F;
        } else if (obj.rx == null) {
            rx = ry = obj.ry.floatValueY(this);
        } else if (obj.ry == null) {
            rx = ry = obj.rx.floatValueX(this);
        } else {
            rx = obj.rx.floatValueX(this);
            ry = obj.ry.floatValueY(this);
        }

        rx = Math.min(rx, obj.width.floatValueX(this) / 2.0F);
        ry = Math.min(ry, obj.height.floatValueY(this) / 2.0F);
        float x = obj.x != null ? obj.x.floatValueX(this) : 0.0F;
        float y = obj.y != null ? obj.y.floatValueY(this) : 0.0F;
        float w = obj.width.floatValueX(this);
        float h = obj.height.floatValueY(this);
        if (obj.boundingBox == null) {
            obj.boundingBox = new Box(x, y, w, h);
        }

        float right = x + w;
        float bottom = y + h;
        android.graphics.Path p = new android.graphics.Path();
        if (rx != 0.0F && ry != 0.0F) {
            float cpx = rx * 0.5522848F;
            float cpy = ry * 0.5522848F;
            p.moveTo(x, y + ry);
            p.cubicTo(x, y + ry - cpy, x + rx - cpx, y, x + rx, y);
            p.lineTo(right - rx, y);
            p.cubicTo(right - rx + cpx, y, right, y + ry - cpy, right, y + ry);
            p.lineTo(right, bottom - ry);
            p.cubicTo(right, bottom - ry + cpy, right - rx + cpx, bottom, right - rx, bottom);
            p.lineTo(x + rx, bottom);
            p.cubicTo(x + rx - cpx, bottom, x, bottom - ry + cpy, x, bottom - ry);
            p.lineTo(x, y + ry);
        } else {
            p.moveTo(x, y);
            p.lineTo(right, y);
            p.lineTo(right, bottom);
            p.lineTo(x, bottom);
            p.lineTo(x, y);
        }

        p.close();
        return p;
    }

    private android.graphics.Path makePathAndBoundingBox(Circle obj) {
        float cx = obj.cx != null ? obj.cx.floatValueX(this) : 0.0F;
        float cy = obj.cy != null ? obj.cy.floatValueY(this) : 0.0F;
        float r = obj.r.floatValue(this);
        float left = cx - r;
        float top = cy - r;
        float right = cx + r;
        float bottom = cy + r;
        if (obj.boundingBox == null) {
            obj.boundingBox = new Box(left, top, r * 2.0F, r * 2.0F);
        }

        float cp = r * 0.5522848F;
        android.graphics.Path p = new android.graphics.Path();
        p.moveTo(cx, top);
        p.cubicTo(cx + cp, top, right, cy - cp, right, cy);
        p.cubicTo(right, cy + cp, cx + cp, bottom, cx, bottom);
        p.cubicTo(cx - cp, bottom, left, cy + cp, left, cy);
        p.cubicTo(left, cy - cp, cx - cp, top, cx, top);
        p.close();
        return p;
    }

    private android.graphics.Path makePathAndBoundingBox(Ellipse obj) {
        float cx = obj.cx != null ? obj.cx.floatValueX(this) : 0.0F;
        float cy = obj.cy != null ? obj.cy.floatValueY(this) : 0.0F;
        float rx = obj.rx.floatValueX(this);
        float ry = obj.ry.floatValueY(this);
        float left = cx - rx;
        float top = cy - ry;
        float right = cx + rx;
        float bottom = cy + ry;
        if (obj.boundingBox == null) {
            obj.boundingBox = new Box(left, top, rx * 2.0F, ry * 2.0F);
        }

        float cpx = rx * 0.5522848F;
        float cpy = ry * 0.5522848F;
        android.graphics.Path p = new android.graphics.Path();
        p.moveTo(cx, top);
        p.cubicTo(cx + cpx, top, right, cy - cpy, right, cy);
        p.cubicTo(right, cy + cpy, cx + cpx, bottom, cx, bottom);
        p.cubicTo(cx - cpx, bottom, left, cy + cpy, left, cy);
        p.cubicTo(left, cy - cpy, cx - cpx, top, cx, top);
        p.close();
        return p;
    }

    private android.graphics.Path makePathAndBoundingBox(PolyLine obj) {
        android.graphics.Path path = new android.graphics.Path();
        path.moveTo(obj.points[0], obj.points[1]);

        for(int i = 2; i < obj.points.length; i += 2) {
            path.lineTo(obj.points[i], obj.points[i + 1]);
        }

        if (obj instanceof Polygon) {
            path.close();
        }

        if (obj.boundingBox == null) {
            obj.boundingBox = this.calculatePathBounds(path);
        }

        path.setFillType(this.getClipRuleFromState());
        return path;
    }

    private void fillWithPattern(SvgElement obj, android.graphics.Path path, Pattern pattern) {
        boolean patternUnitsAreUser = pattern.patternUnitsAreUser != null && pattern.patternUnitsAreUser;
        if (pattern.href != null) {
            this.fillInChainedPatternFields(pattern, pattern.href);
        }

        float x;
        float y;
        float w;
        float h;
        if (patternUnitsAreUser) {
            x = pattern.x != null ? pattern.x.floatValueX(this) : 0.0F;
            y = pattern.y != null ? pattern.y.floatValueY(this) : 0.0F;
            w = pattern.width != null ? pattern.width.floatValueX(this) : 0.0F;
            h = pattern.height != null ? pattern.height.floatValueY(this) : 0.0F;
        } else {
            x = pattern.x != null ? pattern.x.floatValue(this, 1.0F) : 0.0F;
            y = pattern.y != null ? pattern.y.floatValue(this, 1.0F) : 0.0F;
            w = pattern.width != null ? pattern.width.floatValue(this, 1.0F) : 0.0F;
            h = pattern.height != null ? pattern.height.floatValue(this, 1.0F) : 0.0F;
            x = obj.boundingBox.minX + x * obj.boundingBox.width;
            y = obj.boundingBox.minY + y * obj.boundingBox.height;
            w *= obj.boundingBox.width;
            h *= obj.boundingBox.height;
        }

        if (w != 0.0F && h != 0.0F) {
            PreserveAspectRatio positioning = pattern.preserveAspectRatio != null ? pattern.preserveAspectRatio : PreserveAspectRatio.LETTERBOX;
            this.statePush();
            this.canvas.clipPath(path);
            SVGAndroidRenderer.RendererState baseState = new SVGAndroidRenderer.RendererState();
            this.updateStyle(baseState, Style.getDefaultStyle());
            baseState.style.overflow = false;
            this.state = this.findInheritFromAncestorState(pattern, baseState);
            Box patternArea = obj.boundingBox;
            if (pattern.patternTransform != null) {
                this.canvas.concat(pattern.patternTransform);
                Matrix inverse = new Matrix();
                if (pattern.patternTransform.invert(inverse)) {
                    float[] pts = new float[]{obj.boundingBox.minX, obj.boundingBox.minY, obj.boundingBox.maxX(), obj.boundingBox.minY, obj.boundingBox.maxX(), obj.boundingBox.maxY(), obj.boundingBox.minX, obj.boundingBox.maxY()};
                    inverse.mapPoints(pts);
                    RectF rect = new RectF(pts[0], pts[1], pts[0], pts[1]);

                    for(int i = 2; i <= 6; i += 2) {
                        if (pts[i] < rect.left) {
                            rect.left = pts[i];
                        }

                        if (pts[i] > rect.right) {
                            rect.right = pts[i];
                        }

                        if (pts[i + 1] < rect.top) {
                            rect.top = pts[i + 1];
                        }

                        if (pts[i + 1] > rect.bottom) {
                            rect.bottom = pts[i + 1];
                        }
                    }

                    patternArea = new Box(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
                }
            }

            float originX = x + (float)Math.floor((double)((patternArea.minX - x) / w)) * w;
            float originY = y + (float)Math.floor((double)((patternArea.minY - y) / h)) * h;
            float right = patternArea.maxX();
            float bottom = patternArea.maxY();
            Box stepViewBox = new Box(0.0F, 0.0F, w, h);

            for(float stepY = originY; stepY < bottom; stepY += h) {
                for(float stepX = originX; stepX < right; stepX += w) {
                    stepViewBox.minX = stepX;
                    stepViewBox.minY = stepY;
                    this.statePush();
                    if (!this.state.style.overflow) {
                        this.setClipRect(stepViewBox.minX, stepViewBox.minY, stepViewBox.width, stepViewBox.height);
                    }

                    boolean compositing;
                    if (pattern.viewBox != null) {
                        this.canvas.concat(this.calculateViewBoxTransform(stepViewBox, pattern.viewBox, positioning));
                    } else {
                        compositing = pattern.patternContentUnitsAreUser == null || pattern.patternContentUnitsAreUser;
                        this.canvas.translate(stepX, stepY);
                        if (!compositing) {
                            this.canvas.scale(obj.boundingBox.width, obj.boundingBox.height);
                        }
                    }

                    compositing = this.pushLayer();
                    Iterator var21 = pattern.children.iterator();

                    while(var21.hasNext()) {
                        SvgObject child = (SvgObject)var21.next();
                        this.render(child);
                    }

                    if (compositing) {
                        this.popLayer(pattern);
                    }

                    this.statePop();
                }
            }

            this.statePop();
        }
    }

    private void fillInChainedPatternFields(Pattern pattern, String href) {
        SvgObject ref = pattern.document.resolveIRI(href);
        if (ref == null) {
            warn("Pattern reference '%s' not found", href);
        } else if (!(ref instanceof Pattern)) {
            error("Pattern href attributes must point to other pattern elements");
        } else if (ref == pattern) {
            error("Circular reference in pattern href attribute '%s'", href);
        } else {
            Pattern pRef = (Pattern)ref;
            if (pattern.patternUnitsAreUser == null) {
                pattern.patternUnitsAreUser = pRef.patternUnitsAreUser;
            }

            if (pattern.patternContentUnitsAreUser == null) {
                pattern.patternContentUnitsAreUser = pRef.patternContentUnitsAreUser;
            }

            if (pattern.patternTransform == null) {
                pattern.patternTransform = pRef.patternTransform;
            }

            if (pattern.x == null) {
                pattern.x = pRef.x;
            }

            if (pattern.y == null) {
                pattern.y = pRef.y;
            }

            if (pattern.width == null) {
                pattern.width = pRef.width;
            }

            if (pattern.height == null) {
                pattern.height = pRef.height;
            }

            if (pattern.children.isEmpty()) {
                pattern.children = pRef.children;
            }

            if (pattern.viewBox == null) {
                pattern.viewBox = pRef.viewBox;
            }

            if (pattern.preserveAspectRatio == null) {
                pattern.preserveAspectRatio = pRef.preserveAspectRatio;
            }

            if (pRef.href != null) {
                this.fillInChainedPatternFields(pattern, pRef.href);
            }

        }
    }

    private void renderMask(Mask mask, SvgElement obj) {
        debug("Mask render");
        boolean maskUnitsAreUser = mask.maskUnitsAreUser != null && mask.maskUnitsAreUser;
        float var10000;
        float w;
        float h;
        if (maskUnitsAreUser) {
            w = mask.width != null ? mask.width.floatValueX(this) : obj.boundingBox.width;
            h = mask.height != null ? mask.height.floatValueY(this) : obj.boundingBox.height;
            if (mask.x != null) {
                mask.x.floatValueX(this);
            } else {
                var10000 = (float)((double)obj.boundingBox.minX - 0.1D * (double)obj.boundingBox.width);
            }

            if (mask.y != null) {
                mask.y.floatValueY(this);
            } else {
                var10000 = (float)((double)obj.boundingBox.minY - 0.1D * (double)obj.boundingBox.height);
            }
        } else {
            float x = mask.x != null ? mask.x.floatValue(this, 1.0F) : -0.1F;
            float y = mask.y != null ? mask.y.floatValue(this, 1.0F) : -0.1F;
            w = mask.width != null ? mask.width.floatValue(this, 1.0F) : 1.2F;
            h = mask.height != null ? mask.height.floatValue(this, 1.0F) : 1.2F;
            var10000 = obj.boundingBox.minX + x * obj.boundingBox.width;
            var10000 = obj.boundingBox.minY + y * obj.boundingBox.height;
            w *= obj.boundingBox.width;
            h *= obj.boundingBox.height;
        }

        if (w != 0.0F && h != 0.0F) {
            this.statePush();
            this.state = this.findInheritFromAncestorState(mask);
            this.state.style.opacity = 1.0F;
            boolean maskContentUnitsAreUser = mask.maskContentUnitsAreUser == null || mask.maskContentUnitsAreUser;
            if (!maskContentUnitsAreUser) {
                this.canvas.translate(obj.boundingBox.minX, obj.boundingBox.minY);
                this.canvas.scale(obj.boundingBox.width, obj.boundingBox.height);
            }

            this.renderChildren(mask, false);
            this.statePop();
        }
    }

    private class MarkerPositionCalculator implements PathInterface {
        private List<SVGAndroidRenderer.MarkerVector> markers = new ArrayList();
        private float startX;
        private float startY;
        private SVGAndroidRenderer.MarkerVector lastPos = null;
        private boolean startArc = false;
        private boolean normalCubic = true;
        private int subpathStartIndex = -1;
        private boolean closepathReAdjustPending;

        public MarkerPositionCalculator(PathDefinition pathDef) {
            pathDef.enumeratePath(this);
            if (this.closepathReAdjustPending) {
                this.lastPos.add((SVGAndroidRenderer.MarkerVector)this.markers.get(this.subpathStartIndex));
                this.markers.set(this.subpathStartIndex, this.lastPos);
                this.closepathReAdjustPending = false;
            }

            if (this.lastPos != null) {
                this.markers.add(this.lastPos);
            }

        }

        public List<SVGAndroidRenderer.MarkerVector> getMarkers() {
            return this.markers;
        }

        public void moveTo(float x, float y) {
            if (this.closepathReAdjustPending) {
                this.lastPos.add((SVGAndroidRenderer.MarkerVector)this.markers.get(this.subpathStartIndex));
                this.markers.set(this.subpathStartIndex, this.lastPos);
                this.closepathReAdjustPending = false;
            }

            if (this.lastPos != null) {
                this.markers.add(this.lastPos);
            }

            this.startX = x;
            this.startY = y;
            this.lastPos = SVGAndroidRenderer.this.new MarkerVector(x, y, 0.0F, 0.0F);
            this.subpathStartIndex = this.markers.size();
        }

        public void lineTo(float x, float y) {
            this.lastPos.add(x, y);
            this.markers.add(this.lastPos);
            SVGAndroidRenderer.MarkerVector newPos = SVGAndroidRenderer.this.new MarkerVector(x, y, x - this.lastPos.x, y - this.lastPos.y);
            this.lastPos = newPos;
            this.closepathReAdjustPending = false;
        }

        public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) {
            if (this.normalCubic || this.startArc) {
                this.lastPos.add(x1, y1);
                this.markers.add(this.lastPos);
                this.startArc = false;
            }

            SVGAndroidRenderer.MarkerVector newPos = SVGAndroidRenderer.this.new MarkerVector(x3, y3, x3 - x2, y3 - y2);
            this.lastPos = newPos;
            this.closepathReAdjustPending = false;
        }

        public void quadTo(float x1, float y1, float x2, float y2) {
            this.lastPos.add(x1, y1);
            this.markers.add(this.lastPos);
            SVGAndroidRenderer.MarkerVector newPos = SVGAndroidRenderer.this.new MarkerVector(x2, y2, x2 - x1, y2 - y1);
            this.lastPos = newPos;
            this.closepathReAdjustPending = false;
        }

        public void arcTo(float rx, float ry, float xAxisRotation, boolean largeArcFlag, boolean sweepFlag, float x, float y) {
            this.startArc = true;
            this.normalCubic = false;
            SVGAndroidRenderer.arcTo(this.lastPos.x, this.lastPos.y, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y, this);
            this.normalCubic = true;
            this.closepathReAdjustPending = false;
        }

        public void close() {
            this.markers.add(this.lastPos);
            this.lineTo(this.startX, this.startY);
            this.closepathReAdjustPending = true;
        }
    }

    private class MarkerVector {
        public float x;
        public float y;
        public float dx = 0.0F;
        public float dy = 0.0F;

        public MarkerVector(float x, float y, float dx, float dy) {
            this.x = x;
            this.y = y;
            double len = Math.sqrt((double)(dx * dx + dy * dy));
            if (len != 0.0D) {
                this.dx = (float)((double)dx / len);
                this.dy = (float)((double)dy / len);
            }

        }

        public void add(float x, float y) {
            float dx = x - this.x;
            float dy = y - this.y;
            double len = Math.sqrt((double)(dx * dx + dy * dy));
            if (len != 0.0D) {
                this.dx += (float)((double)dx / len);
                this.dy += (float)((double)dy / len);
            }

        }

        public void add(SVGAndroidRenderer.MarkerVector v2) {
            this.dx += v2.dx;
            this.dy += v2.dy;
        }

        public String toString() {
            return "(" + this.x + "," + this.y + " " + this.dx + "," + this.dy + ")";
        }
    }

    private class PathConverter implements PathInterface {
        android.graphics.Path path = new android.graphics.Path();
        float lastX;
        float lastY;

        public PathConverter(PathDefinition pathDef) {
            pathDef.enumeratePath(this);
        }

        public android.graphics.Path getPath() {
            return this.path;
        }

        public void moveTo(float x, float y) {
            this.path.moveTo(x, y);
            this.lastX = x;
            this.lastY = y;
        }

        public void lineTo(float x, float y) {
            this.path.lineTo(x, y);
            this.lastX = x;
            this.lastY = y;
        }

        public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) {
            this.path.cubicTo(x1, y1, x2, y2, x3, y3);
            this.lastX = x3;
            this.lastY = y3;
        }

        public void quadTo(float x1, float y1, float x2, float y2) {
            this.path.quadTo(x1, y1, x2, y2);
            this.lastX = x2;
            this.lastY = y2;
        }

        public void arcTo(float rx, float ry, float xAxisRotation, boolean largeArcFlag, boolean sweepFlag, float x, float y) {
            SVGAndroidRenderer.arcTo(this.lastX, this.lastY, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y, this);
            this.lastX = x;
            this.lastY = y;
        }

        public void close() {
            this.path.close();
        }
    }

    private class PathTextDrawer extends SVGAndroidRenderer.PlainTextDrawer {
        private android.graphics.Path path;

        public PathTextDrawer(android.graphics.Path path, float x, float y) {
            super(x, y);
            this.path = path;
        }

        public void processText(String text) {
            if (SVGAndroidRenderer.this.visible()) {
                if (SVGAndroidRenderer.this.state.hasFill) {
                    SVGAndroidRenderer.this.canvas.drawTextOnPath(text, this.path, this.x, this.y, SVGAndroidRenderer.this.state.fillPaint);
                }

                if (SVGAndroidRenderer.this.state.hasStroke) {
                    SVGAndroidRenderer.this.canvas.drawTextOnPath(text, this.path, this.x, this.y, SVGAndroidRenderer.this.state.strokePaint);
                }
            }

            this.x += SVGAndroidRenderer.this.state.fillPaint.measureText(text);
        }
    }

    private class PlainTextDrawer extends SVGAndroidRenderer.TextProcessor {
        public float x;
        public float y;

        public PlainTextDrawer(float x, float y) {
            super((SVGAndroidRenderer.TextProcessor)null);
            this.x = x;
            this.y = y;
        }

        public void processText(String text) {
            SVGAndroidRenderer.debug("TextSequence render");
            if (SVGAndroidRenderer.this.visible()) {
                if (SVGAndroidRenderer.this.state.hasFill) {
                    SVGAndroidRenderer.this.canvas.drawText(text, this.x, this.y, SVGAndroidRenderer.this.state.fillPaint);
                }

                if (SVGAndroidRenderer.this.state.hasStroke) {
                    SVGAndroidRenderer.this.canvas.drawText(text, this.x, this.y, SVGAndroidRenderer.this.state.strokePaint);
                }
            }

            this.x += SVGAndroidRenderer.this.state.fillPaint.measureText(text);
        }
    }

    private class PlainTextToPath extends SVGAndroidRenderer.TextProcessor {
        public float x;
        public float y;
        public android.graphics.Path textAsPath;

        public PlainTextToPath(float x, float y, android.graphics.Path textAsPath) {
            super((SVGAndroidRenderer.TextProcessor)null);
            this.x = x;
            this.y = y;
            this.textAsPath = textAsPath;
        }

        public boolean doTextContainer(TextContainer obj) {
            if (obj instanceof TextPath) {
                SVGAndroidRenderer.warn("Using <textPath> elements in a clip path is not supported.");
                return false;
            } else {
                return true;
            }
        }

        public void processText(String text) {
            if (SVGAndroidRenderer.this.visible()) {
                android.graphics.Path spanPath = new android.graphics.Path();
                SVGAndroidRenderer.this.state.fillPaint.getTextPath(text, 0, text.length(), this.x, this.y, spanPath);
                this.textAsPath.addPath(spanPath);
            }

            this.x += SVGAndroidRenderer.this.state.fillPaint.measureText(text);
        }
    }

    private class RendererState implements Cloneable {
        public Style style;
        public boolean hasFill;
        public boolean hasStroke;
        public Paint fillPaint = new Paint();
        public Paint strokePaint;
        public Box viewPort;
        public Box viewBox;
        public boolean spacePreserve;
        public boolean directRendering;

        public RendererState() {
            this.fillPaint.setFlags(385);
            this.fillPaint.setStyle(android.graphics.Paint.Style.FILL);
            this.fillPaint.setTypeface(Typeface.DEFAULT);
            this.strokePaint = new Paint();
            this.strokePaint.setFlags(385);
            this.strokePaint.setStyle(android.graphics.Paint.Style.STROKE);
            this.strokePaint.setTypeface(Typeface.DEFAULT);
            this.style = Style.getDefaultStyle();
        }

        protected Object clone() {
            try {
                SVGAndroidRenderer.RendererState obj = (SVGAndroidRenderer.RendererState)super.clone();
                obj.style = (Style)this.style.clone();
                obj.fillPaint = new Paint(this.fillPaint);
                obj.strokePaint = new Paint(this.strokePaint);
                return obj;
            } catch (CloneNotSupportedException var3) {
                throw new InternalError(var3.toString());
            }
        }
    }

    private class TextBoundsCalculator extends SVGAndroidRenderer.TextProcessor {
        float x;
        float y;
        RectF bbox = new RectF();

        public TextBoundsCalculator(float x, float y) {
            super((SVGAndroidRenderer.TextProcessor)null);
            this.x = x;
            this.y = y;
        }

        public boolean doTextContainer(TextContainer obj) {
            if (obj instanceof TextPath) {
                TextPath tpath = (TextPath)obj;
                SvgObject ref = obj.document.resolveIRI(tpath.href);
                if (ref == null) {
                    SVGAndroidRenderer.error("TextPath path reference '%s' not found", tpath.href);
                    return false;
                } else {
                    Path pathObj = (Path)ref;
                    android.graphics.Path path = (SVGAndroidRenderer.this.new PathConverter(pathObj.d)).getPath();
                    if (pathObj.transform != null) {
                        path.transform(pathObj.transform);
                    }

                    RectF pathBounds = new RectF();
                    path.computeBounds(pathBounds, true);
                    this.bbox.union(pathBounds);
                    return false;
                }
            } else {
                return true;
            }
        }

        public void processText(String text) {
            if (SVGAndroidRenderer.this.visible()) {
                android.graphics.Rect rect = new android.graphics.Rect();
                SVGAndroidRenderer.this.state.fillPaint.getTextBounds(text, 0, text.length(), rect);
                RectF textbounds = new RectF(rect);
                textbounds.offset(this.x, this.y);
                this.bbox.union(textbounds);
            }

            this.x += SVGAndroidRenderer.this.state.fillPaint.measureText(text);
        }
    }

    private abstract class TextProcessor {
        private TextProcessor() {
        }

        public TextProcessor(TextProcessor textProcessor) {

        }

        public boolean doTextContainer(TextContainer obj) {
            return true;
        }

        public abstract void processText(String var1);
    }

    private class TextWidthCalculator extends SVGAndroidRenderer.TextProcessor {
        public float x;

        private TextWidthCalculator(TextWidthCalculator textWidthCalculator) {
            super((SVGAndroidRenderer.TextProcessor)null);
            this.x = 0.0F;
        }

        public void processText(String text) {
            this.x += SVGAndroidRenderer.this.state.fillPaint.measureText(text);
        }
    }
}
